Skip to content

Commit 467edea

Browse files
committed
add rust.capnp with an annotation for renaming fields
1 parent f945e34 commit 467edea

File tree

5 files changed

+58
-6
lines changed

5 files changed

+58
-6
lines changed

capnpc/rust.capnp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@0x83b3c14c3c8dd083;
2+
3+
annotation name @0xc2fe4c6d100166d0 (field) :Text;
4+
# Rename something in the generated code.
5+
# Currently, only field renaming is supported.

capnpc/src/codegen.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,21 @@ fn module_name(camel_case : &str) -> String {
237237
name
238238
}
239239

240+
const NAME_ANNOTATION_ID: u64 = 0xc2fe4c6d100166d0;
241+
242+
fn get_field_name(field: schema_capnp::field::Reader) -> capnp::Result<&str> {
243+
for annotation in field.get_annotations()?.iter() {
244+
if annotation.get_id() == NAME_ANNOTATION_ID {
245+
if let schema_capnp::value::Text(t) = annotation.get_value()?.which()? {
246+
return t;
247+
} else {
248+
return Err(capnp::Error::failed(format!("expected rust.name annotation value to be of type Text")));
249+
}
250+
}
251+
}
252+
field.get_name()
253+
}
254+
240255
fn populate_scope_map(node_map: &collections::hash_map::HashMap<u64, schema_capnp::node::Reader>,
241256
scope_map: &mut collections::hash_map::HashMap<u64, Vec<String>>,
242257
scope_names: Vec<String>,
@@ -274,7 +289,7 @@ fn populate_scope_map(node_map: &collections::hash_map::HashMap<u64, schema_capn
274289
for field in fields.iter() {
275290
match field.which() {
276291
Ok(schema_capnp::field::Group(group)) => {
277-
let name = module_name(field.get_name()?);
292+
let name = module_name(get_field_name(field)?);
278293
let mut scope_names = scope_names.clone();
279294
scope_names.push(name);
280295
populate_scope_map(node_map, scope_map, scope_names, group.get_type_id())?;
@@ -371,7 +386,7 @@ pub fn getter_text(gen: &GeneratorContext,
371386
let typ = raw_type.type_string(gen, module)?;
372387
let default_value = reg_field.get_default_value()?;
373388
let default = default_value.which()?;
374-
let default_name = format!("DEFAULT_{}", snake_to_upper_case(&camel_to_snake_case(field.get_name()?)));
389+
let default_name = format!("DEFAULT_{}", snake_to_upper_case(&camel_to_snake_case(get_field_name(*field)?)));
375390

376391
let mut result_type = match raw_type.which()? {
377392
type_::Enum(_) => format!("::std::result::Result<{},::capnp::NotInSchema>", typ),
@@ -778,7 +793,7 @@ fn generate_union(gen: &GeneratorContext,
778793

779794
let dvalue = field.get_discriminant_value() as usize;
780795

781-
let field_name = field.get_name()?;
796+
let field_name = get_field_name(*field)?;
782797
let enumerant_name = capitalize_first_letter(field_name);
783798

784799
let (ty, get, maybe_default_decl) = getter_text(gen, field, is_reader, false)?;
@@ -907,7 +922,7 @@ fn generate_pipeline_getter(gen: &GeneratorContext,
907922
field: schema_capnp::field::Reader) -> ::capnp::Result<FormattedText> {
908923
use crate::schema_capnp::{field, type_};
909924

910-
let name = field.get_name()?;
925+
let name = get_field_name(field)?;
911926

912927
match field.which()? {
913928
field::Group(group) => {
@@ -1094,7 +1109,7 @@ fn generate_node(gen: &GeneratorContext,
10941109

10951110
let fields = struct_reader.get_fields()?;
10961111
for field in fields.iter() {
1097-
let name = field.get_name()?;
1112+
let name = get_field_name(field)?;
10981113
let styled_name = camel_to_snake_case(name);
10991114

11001115
let discriminant_value = field.get_discriminant_value();
@@ -1160,7 +1175,7 @@ fn generate_node(gen: &GeneratorContext,
11601175
reexports.push_str("pub use self::Which::{");
11611176
let mut whichs = Vec::new();
11621177
for f in union_fields.iter(){
1163-
whichs.push(capitalize_first_letter(f.get_name()?));
1178+
whichs.push(capitalize_first_letter(get_field_name(*f)?));
11641179
}
11651180
reexports.push_str(&whichs.join(","));
11661181
reexports.push_str("};");

capnpc/test/rust.capnp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../rust.capnp

capnpc/test/test.capnp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
@0x99d187209d25cee7;
2424

25+
using Rust = import "rust.capnp";
26+
2527
struct TestPrimList {
2628
uint8List @0 : List(UInt8);
2729
int8List @1 : List(Int8);
@@ -744,3 +746,13 @@ struct Map(Key, Value) {
744746
interface GenericBase(T) {}
745747
interface GenericExtend extends(GenericBase(Data)) {}
746748
interface GenericExtend2 extends (GenericBase(GenericBase(Data))) {}
749+
750+
struct TestNameAnnotation {
751+
union {
752+
badFieldName @0 :Bool $Rust.name("goodFieldName");
753+
bar @1 :Int8;
754+
}
755+
756+
anotherBadFieldName @2 :UInt16 $Rust.name("anotherGoodFieldName");
757+
# ...
758+
}

capnpc/test/test.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,4 +1473,23 @@ mod tests {
14731473
assert!(overflow_iter.next().is_none());
14741474
}
14751475
}
1476+
1477+
#[test]
1478+
fn name_annotation() {
1479+
use test_capnp::test_name_annotation;
1480+
let mut message = message::Builder::new_default();
1481+
{
1482+
let mut root: test_name_annotation::Builder = message.init_root();
1483+
root.set_good_field_name(true);
1484+
root.set_another_good_field_name(17);
1485+
}
1486+
{
1487+
let root: test_name_annotation::Reader = message.get_root_as_reader().unwrap();
1488+
match root.which().unwrap() {
1489+
test_name_annotation::GoodFieldName(true) => (),
1490+
_ => panic!("expected GoodFieldName(true)"),
1491+
}
1492+
assert_eq!(17, root.get_another_good_field_name());
1493+
}
1494+
}
14761495
}

0 commit comments

Comments
 (0)