From 40d3ccb5d3f82ea88fcd9316abbb9ebe528fe9d5 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 23 Nov 2020 17:22:15 +0000 Subject: [PATCH 01/11] Add display name to field, tests failing --- derive/src/lib.rs | 44 +++++++++++++++++------ src/build.rs | 73 ++++++++++++++++++++++++++++---------- src/ty/fields.rs | 38 ++++++++++---------- test_suite/tests/derive.rs | 21 +++++++++-- 4 files changed, 126 insertions(+), 50 deletions(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index e3a7875e..53165301 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -19,7 +19,7 @@ extern crate proc_macro; mod impl_wrapper; -use alloc::vec::Vec; +use alloc::{string::ToString, vec::Vec}; use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::quote; @@ -91,15 +91,39 @@ fn generate_fields(fields: &FieldsList) -> Vec { .iter() .map(|f| { let (ty, ident) = (&f.ty, &f.ident); - if let Some(i) = ident { - quote! { - .field_of::<#ty>(stringify!(#i)) - } - } else { - quote! { - .field_of::<#ty>() - } - } + + let display_name = + if let syn::Type::Path(type_path) = ty { + if type_path.qself.is_some() || type_path.path.segments.is_empty() { + quote! {} + } else { + let segs = type_path + .path + .segments + .iter() + .map(|seg| seg.ident.to_string()) + .collect::>(); + quote! { + .with_type_display_name( + vec![#(#segs),*].into_iter().map(AsRef::as_ref) + ) + } + } + } else { + quote! {} + }; + + let field = + if let Some(i) = ident { + quote! { + _scale_info::Field::named_of::<#ty>(stringify!(#i))#display_name + } + } else { + quote! { + _scale_info::Field::unnamed_of::<#ty>()#display_name + } + }; + quote! { .field(#field) } }) .collect() } diff --git a/src/build.rs b/src/build.rs index a0ac2ce5..a21378e9 100644 --- a/src/build.rs +++ b/src/build.rs @@ -209,7 +209,7 @@ impl Fields { /// Build a set of either all named (e.g. for a struct) or all unnamed (e.g. for a tuple struct) pub struct FieldsBuilder { - fields: Vec>, + fields: Vec>, marker: PhantomData T>, } @@ -223,36 +223,29 @@ impl Default for FieldsBuilder { } impl FieldsBuilder { + /// Add a field with the type of the type parameter `T` + pub fn field(mut self, field: FieldBuilder) -> Self { + self.fields.push(field); + self + } + /// Complete building and return the set of fields - pub fn done(self) -> Vec> { - self.fields + pub fn done(mut self) -> Vec> { + self.fields.drain(..).map(|field| field.done()).collect() } } impl FieldsBuilder { - /// Add a named field with the given [`MetaType`](`crate::MetaType`) instance - pub fn field(mut self, name: &'static str, ty: MetaType) -> Self { - self.fields.push(Field::named(name, ty)); - self - } - /// Add a named field with the type of the type parameter `T` - pub fn field_of(mut self, name: &'static str) -> Self + pub fn field_of(self, name: &'static str) -> Self where T: TypeInfo + ?Sized + 'static, { - self.fields.push(Field::named_of::(name)); - self + self.field(Field::named_of::(name)) } } impl FieldsBuilder { - /// Add an unnamed field with the given [`MetaType`](`crate::MetaType`) instance - pub fn field(mut self, ty: MetaType) -> Self { - self.fields.push(Field::unnamed(ty)); - self - } - /// Add an unnamed field with the type of the type parameter `T` pub fn field_of(mut self) -> Self where @@ -263,6 +256,50 @@ impl FieldsBuilder { } } +/// Build a field. +pub struct FieldBuilder { + name: Option<&'static str>, + ty: MetaType, + ty_display_name: Option, + marker: PhantomData T>, +} + +impl FieldBuilder { + /// Create a new field builder for a field with the given [`MetaType`]. + pub fn new(ty: MetaType) -> Self { + Self { + name: None, + ty, + ty_display_name: None, + marker: PhantomData, + } + } + + /// Specify the display name of the type of the field. This can either be the type name itself + /// or a type alias. + pub fn with_type_display_name(mut self, path_segments: S) -> Self + where + S: IntoIterator, + { + let path = Path::from_segments(path_segments).expect("display name is invalid"); + self.ty_display_name = Some(path); + self + } + + /// Complete building the field. + pub fn done(self) -> Field { + Field::new(self.name, self.ty, self.ty_display_name) + } +} + +impl FieldBuilder { + /// Specify the name of the field. + pub fn with_name(mut self, name: &'static str) -> Self { + self.name = Some(name); + self + } +} + /// Build a type with no variants. pub enum NoVariants {} /// Build a type where at least one variant has fields. diff --git a/src/ty/fields.rs b/src/ty/fields.rs index 1ac29bda..ecd901cc 100644 --- a/src/ty/fields.rs +++ b/src/ty/fields.rs @@ -15,8 +15,9 @@ use crate::tm_std::*; use crate::{ + build::{FieldBuilder, NamedFields, UnnamedFields}, form::{CompactForm, Form, MetaForm}, - IntoCompact, MetaType, Registry, TypeInfo, + IntoCompact, MetaType, Path, Registry, TypeInfo, }; use scale::{Decode, Encode}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -31,6 +32,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; serialize = "T::Type: Serialize, T::String: Serialize", deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned" ))] +#[serde(rename_all = "camelCase")] pub struct Field { /// The name of the field. None for unnamed fields. #[serde(skip_serializing_if = "Option::is_none", default)] @@ -38,6 +40,12 @@ pub struct Field { /// The type of the field. #[serde(rename = "type")] ty: T::Type, + /// The compile-time known displayed representation of the type of the field. This will be the + /// actual name of the type or an alias of it. + /// + /// Will be `None` if the type has a qualified type path e.g. `::AssociatedItem`. + #[serde(skip_serializing_if = "Option::is_none", default)] + display_name: Option>, } impl IntoCompact for Field { @@ -47,6 +55,9 @@ impl IntoCompact for Field { Field { name: self.name.map(|name| name.into_compact(registry)), ty: registry.register_type(&self.ty), + display_name: self + .display_name + .map(|display_name| display_name.into_compact(registry)), } } } @@ -55,43 +66,30 @@ impl Field { /// Creates a new field. /// /// Use this constructor if you want to instantiate from a given meta type. - pub fn new(name: Option<&'static str>, ty: MetaType) -> Self { - Self { name, ty } - } - - /// Creates a new named field - pub fn named(name: &'static str, ty: MetaType) -> Self { - Self::new(Some(name), ty) + pub fn new(name: Option<&'static str>, ty: MetaType, display_name: Option) -> Self { + Self { name, ty, display_name } } /// Creates a new named field. /// /// Use this constructor if you want to instantiate from a given /// compile-time type. - pub fn named_of(name: &'static str) -> Self + pub fn named_of(name: &'static str) -> FieldBuilder where T: TypeInfo + ?Sized + 'static, { - Self::new(Some(name), MetaType::new::()) - } - - /// Creates a new unnamed field. - /// - /// Use this constructor if you want to instantiate an unnamed field from a - /// given meta type. - pub fn unnamed(meta_type: MetaType) -> Self { - Self::new(None, meta_type) + FieldBuilder::::new(MetaType::new::()).with_name(name) } /// Creates a new unnamed field. /// /// Use this constructor if you want to instantiate an unnamed field from a /// given compile-time type. - pub fn unnamed_of() -> Self + pub fn unnamed_of() -> FieldBuilder where T: TypeInfo + ?Sized + 'static, { - Self::new(None, MetaType::new::()) + FieldBuilder::::new(MetaType::new::()) } } diff --git a/test_suite/tests/derive.rs b/test_suite/tests/derive.rs index d50e694a..855c9ee9 100644 --- a/test_suite/tests/derive.rs +++ b/test_suite/tests/derive.rs @@ -18,11 +18,11 @@ extern crate alloc; #[cfg(not(feature = "std"))] -use alloc::boxed::Box; +use alloc::{boxed::Box, vec}; use pretty_assertions::assert_eq; use scale_info::build::*; -use scale_info::{tuple_meta_type, Path, Type, TypeInfo}; +use scale_info::{tuple_meta_type, Field, Path, Type, TypeInfo}; fn assert_type(expected: E) where @@ -128,3 +128,20 @@ fn enum_derive() { assert_type!(E, ty); } + +#[test] +fn fields_with_type_alias() { + type BoolAlias = bool; + + #[allow(unused)] + #[derive(TypeInfo)] + struct S { + a: BoolAlias, + } + + let ty = Type::builder() + .path(Path::new("S", "derive")) + .composite(Fields::named().field(Field::named_of::("a").with_type_display_name(vec!["BoolAlias"]))); + + assert_type!(S, ty); +} From b6086c36d69df4058e71b32d009a47a1db9a1063 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 24 Nov 2020 15:07:50 +0000 Subject: [PATCH 02/11] Fix up some tests with display names --- test_suite/tests/derive.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test_suite/tests/derive.rs b/test_suite/tests/derive.rs index 855c9ee9..4c22627b 100644 --- a/test_suite/tests/derive.rs +++ b/test_suite/tests/derive.rs @@ -50,7 +50,11 @@ fn struct_derive() { let struct_type = Type::builder() .path(Path::new("S", "derive")) .type_params(tuple_meta_type!(bool, u8)) - .composite(Fields::named().field_of::("t").field_of::("u")); + .composite( + Fields::named() + .field_of::("t") + .field_of::("u") + ); assert_type!(S, struct_type); @@ -121,8 +125,8 @@ fn enum_derive() { .type_params(tuple_meta_type!(bool)) .variant( Variants::with_fields() - .variant("A", Fields::unnamed().field_of::()) - .variant("B", Fields::named().field_of::("b")) + .variant("A", Fields::unnamed().field(Field::unnamed_of::().with_type_display_name(vec!["T"]))) + .variant("B", Fields::named().field(Field::named_of::("b").with_type_display_name(vec!["T"]))) .variant_unit("C"), ); From 105571c9e02faaf520598fb5ea4638ec84db1736 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 24 Nov 2020 15:43:06 +0000 Subject: [PATCH 03/11] Fix up derive tests --- test_suite/tests/derive.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test_suite/tests/derive.rs b/test_suite/tests/derive.rs index 4c22627b..9d89a796 100644 --- a/test_suite/tests/derive.rs +++ b/test_suite/tests/derive.rs @@ -52,8 +52,8 @@ fn struct_derive() { .type_params(tuple_meta_type!(bool, u8)) .composite( Fields::named() - .field_of::("t") - .field_of::("u") + .field(Field::named_of::("t").with_type_display_name(vec!["T"])) + .field(Field::named_of::("u").with_type_display_name(vec!["U"])) ); assert_type!(S, struct_type); @@ -65,7 +65,10 @@ fn struct_derive() { let self_typed_type = Type::builder() .path(Path::new("S", "derive")) .type_params(tuple_meta_type!(Box>, bool)) - .composite(Fields::named().field_of::>>("t").field_of::("u")); + .composite(Fields::named() + .field(Field::named_of::>>("t").with_type_display_name(vec!["T"])) + .field(Field::named_of::("u").with_type_display_name(vec!["U"])) + ); assert_type!(SelfTyped, self_typed_type); } @@ -78,7 +81,7 @@ fn tuple_struct_derive() { let ty = Type::builder() .path(Path::new("S", "derive")) .type_params(tuple_meta_type!(bool)) - .composite(Fields::unnamed().field_of::()); + .composite(Fields::unnamed().field(Field::unnamed_of::().with_type_display_name(vec!["T"]))); assert_type!(S, ty); } From 7c0fdf7533e274972374f972b25d954135cf9cdc Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 24 Nov 2020 15:53:05 +0000 Subject: [PATCH 04/11] Add display names to json tests --- test_suite/tests/json.rs | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/test_suite/tests/json.rs b/test_suite/tests/json.rs index 74c68673..80a12d24 100644 --- a/test_suite/tests/json.rs +++ b/test_suite/tests/json.rs @@ -146,9 +146,9 @@ fn test_tuplestruct() { "def": { "composite": { "fields": [ - { "type": 1 }, + { "type": 1, "displayName": ["i32"] }, { "type": 2 }, - { "type": 4 }, + { "type": 4, "displayName": ["bool"] }, ], }, } @@ -169,9 +169,9 @@ fn test_struct() { "def": { "composite": { "fields": [ - { "name": "a", "type": 1, }, - { "name": "b", "type": 2, }, - { "name": "c", "type": 4, }, + { "name": "a", "type": 1, "displayName": ["i32"] }, + { "name": "b", "type": 2 }, + { "name": "c", "type": 4, "displayName": ["bool"] }, ], }, } @@ -219,16 +219,16 @@ fn test_enum() { { "name": "TupleStructVariant", "fields": [ - { "type": 1 }, - { "type": 2 }, + { "type": 1, "displayName": ["u32"] }, + { "type": 2, "displayName": ["bool"] }, ], }, { "name": "StructVariant", "fields": [ - { "name": "a", "type": 1, }, - { "name": "b", "type": 3, }, - { "name": "c", "type": 5, }, + { "name": "a", "type": 1, "displayName": ["u32"] }, + { "name": "b", "type": 3 }, + { "name": "c", "type": 5, "displayName": ["char"] }, ], } ], @@ -294,8 +294,8 @@ fn test_registry() { "def": { "composite": { "fields": [ - { "type": 3 }, - { "type": 4 }, + { "type": 3, "displayName": ["u8"] }, + { "type": 4, "displayName": ["u32"] }, ], }, } @@ -316,11 +316,13 @@ fn test_registry() { "fields": [ { "name": "a", - "type": 3, // u8 + "type": 3, + "displayName": ["u8"] }, { "name": "b", - "type": 4, // u32 + "type": 4, + "displayName": ["u32"] }, { "name": "c", @@ -349,6 +351,7 @@ fn test_registry() { { "name": "rec", "type": 8, // Vec + "displayName": ["Vec"] } ] }, @@ -399,8 +402,8 @@ fn test_registry() { { "name": "B", "fields": [ - { "type": 3 }, // u8 - { "type": 4 }, // u32 + { "type": 3, "displayName": ["u8"] }, // u8 + { "type": 4, "displayName": ["u32"] }, // u32 ] }, { @@ -409,10 +412,12 @@ fn test_registry() { { "name": "a", "type": 3, // u8 + "displayName": ["u8"] }, { "name": "b", "type": 4, // u32 + "displayName": ["u32"] }, { "name": "c", From b6e83cb170a8d2bebde48ff2fab985fd0a36e200 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 24 Nov 2020 16:11:08 +0000 Subject: [PATCH 05/11] Fix up recursive types test --- test_suite/tests/derive.rs | 6 +++--- test_suite/tests/json.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test_suite/tests/derive.rs b/test_suite/tests/derive.rs index d82f6da9..245b4f96 100644 --- a/test_suite/tests/derive.rs +++ b/test_suite/tests/derive.rs @@ -147,12 +147,12 @@ fn recursive_type_derive() { let ty = Type::builder().path(Path::new("Tree", "derive")).variant( Variants::with_fields() - .variant("Leaf", Fields::named().field_of::("value")) + .variant("Leaf", Fields::named().field(Field::named_of::("value").with_type_display_name(vec!["i32"]))) .variant( "Node", Fields::named() - .field_of::>("right") - .field_of::>("left"), + .field(Field::named_of::>("right").with_type_display_name(vec!["Box"])) + .field(Field::named_of::>("left").with_type_display_name(vec!["Box"])), ), ); diff --git a/test_suite/tests/json.rs b/test_suite/tests/json.rs index 739316c3..d27e10b5 100644 --- a/test_suite/tests/json.rs +++ b/test_suite/tests/json.rs @@ -258,14 +258,14 @@ fn test_recursive_type_with_box() { { "name": "Leaf", "fields": [ - { "name": "value", "type": 2 }, + { "name": "value", "type": 2, "displayName": ["i32"] }, ], }, { "name": "Node", "fields": [ - { "name": "right", "type": 1, }, - { "name": "left", "type": 1, }, + { "name": "right", "type": 1, "displayName": ["Box"] }, + { "name": "left", "type": 1, "displayName": ["Box"] }, ], } ], From 2f232415f94c081579c5756e45a4c9478cff5db6 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 24 Nov 2020 16:27:49 +0000 Subject: [PATCH 06/11] Fmt --- derive/src/lib.rs | 52 ++++++++++++++++++-------------------- test_suite/tests/derive.rs | 24 +++++++++++++----- 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 08356015..0caa43b0 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -93,37 +93,35 @@ fn generate_fields(fields: &FieldsList) -> Vec { .map(|f| { let (ty, ident) = (&f.ty, &f.ident); - let display_name = - if let syn::Type::Path(type_path) = ty { - if type_path.qself.is_some() || type_path.path.segments.is_empty() { - quote! {} - } else { - let segs = type_path - .path - .segments - .iter() - .map(|seg| seg.ident.to_string()) - .collect::>(); - quote! { - .with_type_display_name( - vec![#(#segs),*].into_iter().map(AsRef::as_ref) - ) - } - } - } else { + let display_name = if let syn::Type::Path(type_path) = ty { + if type_path.qself.is_some() || type_path.path.segments.is_empty() { quote! {} - }; - - let field = - if let Some(i) = ident { - quote! { - _scale_info::Field::named_of::<#ty>(stringify!(#i))#display_name - } } else { + let segs = type_path + .path + .segments + .iter() + .map(|seg| seg.ident.to_string()) + .collect::>(); quote! { - _scale_info::Field::unnamed_of::<#ty>()#display_name + .with_type_display_name( + vec![#(#segs),*].into_iter().map(AsRef::as_ref) + ) } - }; + } + } else { + quote! {} + }; + + let field = if let Some(i) = ident { + quote! { + _scale_info::Field::named_of::<#ty>(stringify!(#i))#display_name + } + } else { + quote! { + _scale_info::Field::unnamed_of::<#ty>()#display_name + } + }; quote! { .field(#field) } }) .collect() diff --git a/test_suite/tests/derive.rs b/test_suite/tests/derive.rs index 245b4f96..3209f07d 100644 --- a/test_suite/tests/derive.rs +++ b/test_suite/tests/derive.rs @@ -53,7 +53,7 @@ fn struct_derive() { .composite( Fields::named() .field(Field::named_of::("t").with_type_display_name(vec!["T"])) - .field(Field::named_of::("u").with_type_display_name(vec!["U"])) + .field(Field::named_of::("u").with_type_display_name(vec!["U"])), ); assert_type!(S, struct_type); @@ -65,9 +65,10 @@ fn struct_derive() { let self_typed_type = Type::builder() .path(Path::new("S", "derive")) .type_params(tuple_meta_type!(Box>, bool)) - .composite(Fields::named() - .field(Field::named_of::>>("t").with_type_display_name(vec!["T"])) - .field(Field::named_of::("u").with_type_display_name(vec!["U"])) + .composite( + Fields::named() + .field(Field::named_of::>>("t").with_type_display_name(vec!["T"])) + .field(Field::named_of::("u").with_type_display_name(vec!["U"])), ); assert_type!(SelfTyped, self_typed_type); } @@ -128,8 +129,14 @@ fn enum_derive() { .type_params(tuple_meta_type!(bool)) .variant( Variants::with_fields() - .variant("A", Fields::unnamed().field(Field::unnamed_of::().with_type_display_name(vec!["T"]))) - .variant("B", Fields::named().field(Field::named_of::("b").with_type_display_name(vec!["T"]))) + .variant( + "A", + Fields::unnamed().field(Field::unnamed_of::().with_type_display_name(vec!["T"])), + ) + .variant( + "B", + Fields::named().field(Field::named_of::("b").with_type_display_name(vec!["T"])), + ) .variant_unit("C"), ); @@ -147,7 +154,10 @@ fn recursive_type_derive() { let ty = Type::builder().path(Path::new("Tree", "derive")).variant( Variants::with_fields() - .variant("Leaf", Fields::named().field(Field::named_of::("value").with_type_display_name(vec!["i32"]))) + .variant( + "Leaf", + Fields::named().field(Field::named_of::("value").with_type_display_name(vec!["i32"])), + ) .variant( "Node", Fields::named() From 1284f146c471cc8869717c4a18c39b1d4a6d0e5a Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 24 Nov 2020 16:55:19 +0000 Subject: [PATCH 07/11] Fix no_std tests --- derive/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 0caa43b0..8e093fe4 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -105,7 +105,7 @@ fn generate_fields(fields: &FieldsList) -> Vec { .collect::>(); quote! { .with_type_display_name( - vec![#(#segs),*].into_iter().map(AsRef::as_ref) + __core::vec![#(#segs),*].into_iter().map(AsRef::as_ref) ) } } From 7262111b36614b97592e5495a5ec5d6f3648e267 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 25 Nov 2020 10:26:58 +0000 Subject: [PATCH 08/11] Rename done to finalize --- src/build.rs | 12 ++++++------ src/ty/variant.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/build.rs b/src/build.rs index b9f7ceb7..ce1dfafa 100644 --- a/src/build.rs +++ b/src/build.rs @@ -177,12 +177,12 @@ impl TypeBuilder { /// Construct a "variant" type i.e an `enum` pub fn variant(self, builder: VariantsBuilder) -> Type { - self.build(builder.done()) + self.build(builder.finalize()) } /// Construct a "composite" type i.e. a `struct` pub fn composite(self, fields: FieldsBuilder) -> Type { - self.build(TypeDefComposite::new(fields.done())) + self.build(TypeDefComposite::new(fields.finalize())) } } @@ -247,8 +247,8 @@ impl FieldsBuilder { } /// Complete building and return the set of fields - pub fn done(mut self) -> Vec> { - self.fields.drain(..).map(|field| field.done()).collect() + pub fn finalize(mut self) -> Vec> { + self.fields.drain(..).map(|field| field.finalize()).collect() } } @@ -304,7 +304,7 @@ impl FieldBuilder { } /// Complete building the field. - pub fn done(self) -> Field { + pub fn finalize(self) -> Field { Field::new(self.name, self.ty, self.ty_display_name) } } @@ -378,7 +378,7 @@ impl VariantsBuilder { } } - fn done(self) -> TypeDefVariant { + fn finalize(self) -> TypeDefVariant { TypeDefVariant::new(self.variants) } } diff --git a/src/ty/variant.rs b/src/ty/variant.rs index 90b3313c..4541b5e7 100644 --- a/src/ty/variant.rs +++ b/src/ty/variant.rs @@ -186,7 +186,7 @@ impl Variant { pub fn with_fields(name: &'static str, fields: FieldsBuilder) -> Self { Self { name, - fields: fields.done(), + fields: fields.finalize(), discriminant: None, } } From 08eabe25d8e649afbf4c4afe31d6d47c8792ccd5 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 25 Nov 2020 14:26:16 +0000 Subject: [PATCH 09/11] Always provide type name This will display any valid field type name as specified in the source code. --- derive/src/lib.rs | 34 +++-------------- src/build.rs | 77 +++++++------------------------------- src/impls.rs | 8 ++-- src/registry.rs | 11 +++++- src/tests.rs | 12 +++--- src/ty/fields.rs | 60 ++++++++++++++++++----------- test_suite/tests/derive.rs | 65 +++++++------------------------- test_suite/tests/json.rs | 60 +++++++++++++++-------------- 8 files changed, 121 insertions(+), 206 deletions(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index ce439780..28746ebc 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -19,10 +19,7 @@ extern crate proc_macro; mod impl_wrapper; -use alloc::{ - string::ToString, - vec::Vec, -}; +use alloc::vec::Vec; use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::quote; @@ -108,36 +105,15 @@ fn generate_fields(fields: &FieldsList) -> Vec { .map(|f| { let (ty, ident) = (&f.ty, &f.ident); - let display_name = if let syn::Type::Path(type_path) = ty { - if type_path.qself.is_some() || type_path.path.segments.is_empty() { - quote! {} - } else { - let segs = type_path - .path - .segments - .iter() - .map(|seg| seg.ident.to_string()) - .collect::>(); - quote! { - .with_type_display_name( - __core::vec![#(#segs),*].into_iter().map(AsRef::as_ref) - ) - } - } - } else { - quote! {} - }; - - let field = if let Some(i) = ident { + if let Some(i) = ident { quote! { - _scale_info::Field::named_of::<#ty>(stringify!(#i))#display_name + .field_of::<#ty>(stringify!(#i), stringify!(#ty)) } } else { quote! { - _scale_info::Field::unnamed_of::<#ty>()#display_name + .field_of::<#ty>(stringify!(#ty)) } - }; - quote! { .field(#field) } + } }) .collect() } diff --git a/src/build.rs b/src/build.rs index ce1dfafa..4832b3e1 100644 --- a/src/build.rs +++ b/src/build.rs @@ -39,8 +39,8 @@ //! .path(Path::new("Foo", module_path!())) //! .type_params(vec![MetaType::new::()]) //! .composite(Fields::named() -//! .field_of::("bar") -//! .field_of::("data") +//! .field_of::("bar", "T") +//! .field_of::("data", "u64") //! ) //! } //! } @@ -57,8 +57,8 @@ //! Type::builder() //! .path(Path::new("Foo", module_path!())) //! .composite(Fields::unnamed() -//! .field_of::() -//! .field_of::() +//! .field_of::("u32") +//! .field_of::("bool") //! ) //! } //! } @@ -84,8 +84,8 @@ //! .type_params(vec![MetaType::new::()]) //! .variant( //! Variants::with_fields() -//! .variant("A", Fields::unnamed().field_of::()) -//! .variant("B", Fields::named().field_of::("f")) +//! .variant("A", Fields::unnamed().field_of::("T")) +//! .variant("B", Fields::named().field_of::("f", "u32")) //! .variant("C", Fields::unit()) //! ) //! } @@ -226,7 +226,7 @@ impl Fields { /// Build a set of either all named (e.g. for a struct) or all unnamed (e.g. for a tuple struct) pub struct FieldsBuilder { - fields: Vec>, + fields: Vec, marker: PhantomData T>, } @@ -240,79 +240,30 @@ impl Default for FieldsBuilder { } impl FieldsBuilder { - /// Add a field with the type of the type parameter `T` - pub fn field(mut self, field: FieldBuilder) -> Self { - self.fields.push(field); - self - } - /// Complete building and return the set of fields - pub fn finalize(mut self) -> Vec> { - self.fields.drain(..).map(|field| field.finalize()).collect() + pub fn finalize(self) -> Vec> { + self.fields } } impl FieldsBuilder { /// Add a named field with the type of the type parameter `T` - pub fn field_of(self, name: &'static str) -> Self + pub fn field_of(mut self, name: &'static str, type_name: &'static str) -> Self where T: TypeInfo + ?Sized + 'static, { - self.field(Field::named_of::(name)) + self.fields.push(Field::named_of::(name, type_name)); + self } } impl FieldsBuilder { /// Add an unnamed field with the type of the type parameter `T` - pub fn field_of(mut self) -> Self + pub fn field_of(mut self, type_name: &'static str) -> Self where T: TypeInfo + ?Sized + 'static, { - self.fields.push(Field::unnamed_of::()); - self - } -} - -/// Build a field. -pub struct FieldBuilder { - name: Option<&'static str>, - ty: MetaType, - ty_display_name: Option, - marker: PhantomData T>, -} - -impl FieldBuilder { - /// Create a new field builder for a field with the given [`MetaType`]. - pub fn new(ty: MetaType) -> Self { - Self { - name: None, - ty, - ty_display_name: None, - marker: PhantomData, - } - } - - /// Specify the display name of the type of the field. This can either be the type name itself - /// or a type alias. - pub fn with_type_display_name(mut self, path_segments: S) -> Self - where - S: IntoIterator, - { - let path = Path::from_segments(path_segments).expect("display name is invalid"); - self.ty_display_name = Some(path); - self - } - - /// Complete building the field. - pub fn finalize(self) -> Field { - Field::new(self.name, self.ty, self.ty_display_name) - } -} - -impl FieldBuilder { - /// Specify the name of the field. - pub fn with_name(mut self, name: &'static str) -> Self { - self.name = Some(name); + self.fields.push(Field::unnamed_of::(type_name)); self } } diff --git a/src/impls.rs b/src/impls.rs index 9554b589..25d4cc49 100644 --- a/src/impls.rs +++ b/src/impls.rs @@ -121,7 +121,7 @@ where .variant( Variants::with_fields() .variant_unit("None") - .variant("Some", Fields::unnamed().field_of::()), + .variant("Some", Fields::unnamed().field_of::("T")), ) } } @@ -139,8 +139,8 @@ where .type_params(tuple_meta_type!(T, E)) .variant( Variants::with_fields() - .variant("Ok", Fields::unnamed().field_of::()) - .variant("Err", Fields::unnamed().field_of::()), + .variant("Ok", Fields::unnamed().field_of::("T")) + .variant("Err", Fields::unnamed().field_of::("E")), ) } } @@ -156,7 +156,7 @@ where Type::builder() .path(Path::prelude("BTreeMap")) .type_params(tuple_meta_type![(K, V)]) - .composite(Fields::unnamed().field_of::<[(K, V)]>()) + .composite(Fields::unnamed().field_of::<[(K, V)]>("[(K, V)]")) } } diff --git a/src/registry.rs b/src/registry.rs index 609a1db3..fd539be4 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -266,10 +266,17 @@ mod tests { .path(Path::new("RecursiveRefs", module_path!())) .composite( Fields::named() - .field_of::>("boxed") - .field_of::<&'static RecursiveRefs<'static>>("reference") + .field_of::>( + "boxed", + "Box < RecursiveRefs >", + ) + .field_of::<&'static RecursiveRefs<'static>>( + "reference", + "&RecursiveRefs", + ) .field_of::<&'static mut RecursiveRefs<'static>>( "mutable_reference", + "&mut RecursiveRefs", ), ) .into() diff --git a/src/tests.rs b/src/tests.rs index ccb9b8af..1552490c 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -60,7 +60,7 @@ fn prelude_items() { .variant( Variants::with_fields() .variant_unit("None") - .variant("Some", Fields::unnamed().field_of::()) + .variant("Some", Fields::unnamed().field_of::("T")) ) ); assert_type!( @@ -70,8 +70,8 @@ fn prelude_items() { .type_params(tuple_meta_type!(bool, String)) .variant( Variants::with_fields() - .variant("Ok", Fields::unnamed().field_of::()) - .variant("Err", Fields::unnamed().field_of::()) + .variant("Ok", Fields::unnamed().field_of::("T")) + .variant("Err", Fields::unnamed().field_of::("E")) ) ); assert_type!( @@ -133,7 +133,7 @@ fn struct_with_generics() { Type::builder() .path(Path::new("MyStruct", module_path!())) .type_params(tuple_meta_type!(T)) - .composite(Fields::named().field_of::("data")) + .composite(Fields::named().field_of::("data", "T")) .into() } } @@ -142,7 +142,7 @@ fn struct_with_generics() { let struct_bool_type_info = Type::builder() .path(Path::from_segments(vec!["scale_info", "tests", "MyStruct"]).unwrap()) .type_params(tuple_meta_type!(bool)) - .composite(Fields::named().field_of::("data")); + .composite(Fields::named().field_of::("data", "T")); assert_type!(MyStruct, struct_bool_type_info); @@ -151,6 +151,6 @@ fn struct_with_generics() { let expected_type = Type::builder() .path(Path::new("MyStruct", "scale_info::tests")) .type_params(tuple_meta_type!(Box>)) - .composite(Fields::named().field_of::>>("data")); + .composite(Fields::named().field_of::>>("data", "T")); assert_type!(SelfTyped, expected_type); } diff --git a/src/ty/fields.rs b/src/ty/fields.rs index a97edf18..c66df943 100644 --- a/src/ty/fields.rs +++ b/src/ty/fields.rs @@ -15,11 +15,6 @@ use crate::tm_std::*; use crate::{ - build::{ - FieldBuilder, - NamedFields, - UnnamedFields, - }, form::{ CompactForm, Form, @@ -27,7 +22,6 @@ use crate::{ }, IntoCompact, MetaType, - Path, Registry, TypeInfo, }; @@ -45,7 +39,30 @@ use serde::{ /// /// Name is optional so it can represent both named and unnamed fields. /// -/// This can be a named field of a struct type or a struct variant. +/// This can be a named field of a struct type or an enum struct variant. +/// +/// # Type name +/// +/// The `type_name` field contains a string which is the name of the type of the +/// field as it appears in the source code. The exact contents and format of the +/// type name are not specified, but in practice will be the name of any valid +/// type for a field e.g. +/// +/// - Concrete types e.g `"u32"`, `"bool"`, `"Foo"` etc. +/// - Type parameters e.g `"T"`, `"U"` +/// - Generic types e.g `"Vec"`, `"Vec"` +/// - Associated types e.g. `"T::MyType"`, `"::MyType"` +/// - Type aliases e.g. `"MyTypeAlias"`, `"MyTypeAlias"` +/// - Other built in Rust types e.g. arrays, references etc. +/// +/// Note that the type name doesn't correspond to the underlying type of the +/// field, unless using a concrete type directly. Any given type may be referred +/// to by multiple field type names, when using generic type parameters and type +/// aliases. +/// +/// This is intended for informational and diagnostic purposes only. Although it +/// is possible to infer certain properties e.g. whether a type name is a type alias, +/// there are no guarantees provided, and the type name representation may change. #[derive( PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Serialize, Deserialize, Encode, Decode, )] @@ -61,12 +78,8 @@ pub struct Field { /// The type of the field. #[serde(rename = "type")] ty: T::Type, - /// The compile-time known displayed representation of the type of the field. This will be the - /// actual name of the type or an alias of it. - /// - /// Will be `None` if the type has a qualified type path e.g. `::AssociatedItem`. - #[serde(skip_serializing_if = "Option::is_none", default)] - display_name: Option>, + /// The name of the type of the field as it appears in the source code. + type_name: T::String, } impl IntoCompact for Field { @@ -76,9 +89,7 @@ impl IntoCompact for Field { Field { name: self.name.map(|name| name.into_compact(registry)), ty: registry.register_type(&self.ty), - display_name: self - .display_name - .map(|display_name| display_name.into_compact(registry)), + type_name: self.type_name.into_compact(registry), } } } @@ -90,12 +101,12 @@ impl Field { pub fn new( name: Option<&'static str>, ty: MetaType, - display_name: Option, + type_name: &'static str, ) -> Self { Self { name, ty, - display_name, + type_name, } } @@ -103,22 +114,22 @@ impl Field { /// /// Use this constructor if you want to instantiate from a given /// compile-time type. - pub fn named_of(name: &'static str) -> FieldBuilder + pub fn named_of(name: &'static str, type_name: &'static str) -> Field where T: TypeInfo + ?Sized + 'static, { - FieldBuilder::::new(MetaType::new::()).with_name(name) + Self::new(Some(name), MetaType::new::(), type_name) } /// Creates a new unnamed field. /// /// Use this constructor if you want to instantiate an unnamed field from a /// given compile-time type. - pub fn unnamed_of() -> FieldBuilder + pub fn unnamed_of(type_name: &'static str) -> Field where T: TypeInfo + ?Sized + 'static, { - FieldBuilder::::new(MetaType::new::()) + Self::new(None, MetaType::new::(), type_name) } } @@ -135,4 +146,9 @@ where pub fn ty(&self) -> &T::Type { &self.ty } + + /// The name of the type of the field as it appears in the source code. + pub fn type_name(&self) -> &T::String { + &self.type_name + } } diff --git a/test_suite/tests/derive.rs b/test_suite/tests/derive.rs index eee11d83..9f9fad16 100644 --- a/test_suite/tests/derive.rs +++ b/test_suite/tests/derive.rs @@ -18,16 +18,12 @@ extern crate alloc; #[cfg(not(feature = "std"))] -use alloc::{ - boxed::Box, - vec, -}; +use alloc::boxed::Box; use pretty_assertions::assert_eq; use scale_info::{ build::*, tuple_meta_type, - Field, Path, Type, TypeInfo, @@ -61,8 +57,8 @@ fn struct_derive() { .type_params(tuple_meta_type!(bool, u8)) .composite( Fields::named() - .field(Field::named_of::("t").with_type_display_name(vec!["T"])) - .field(Field::named_of::("u").with_type_display_name(vec!["U"])), + .field_of::("t", "T") + .field_of::("u", "U"), ); assert_type!(S, struct_type); @@ -76,11 +72,8 @@ fn struct_derive() { .type_params(tuple_meta_type!(Box>, bool)) .composite( Fields::named() - .field( - Field::named_of::>>("t") - .with_type_display_name(vec!["T"]), - ) - .field(Field::named_of::("u").with_type_display_name(vec!["U"])), + .field_of::>>("t", "T") + .field_of::("u", "U"), ); assert_type!(SelfTyped, self_typed_type); } @@ -94,10 +87,7 @@ fn tuple_struct_derive() { let ty = Type::builder() .path(Path::new("S", "derive")) .type_params(tuple_meta_type!(bool)) - .composite( - Fields::unnamed() - .field(Field::unnamed_of::().with_type_display_name(vec!["T"])), - ); + .composite(Fields::unnamed().field_of::("T")); assert_type!(S, ty); } @@ -146,18 +136,8 @@ fn enum_derive() { .type_params(tuple_meta_type!(bool)) .variant( Variants::with_fields() - .variant( - "A", - Fields::unnamed().field( - Field::unnamed_of::().with_type_display_name(vec!["T"]), - ), - ) - .variant( - "B", - Fields::named().field( - Field::named_of::("b").with_type_display_name(vec!["T"]), - ), - ) + .variant("A", Fields::unnamed().field_of::("T")) + .variant("B", Fields::named().field_of::("b", "T")) .variant_unit("C"), ); @@ -175,23 +155,12 @@ fn recursive_type_derive() { let ty = Type::builder().path(Path::new("Tree", "derive")).variant( Variants::with_fields() - .variant( - "Leaf", - Fields::named().field( - Field::named_of::("value").with_type_display_name(vec!["i32"]), - ), - ) + .variant("Leaf", Fields::named().field_of::("value", "i32")) .variant( "Node", Fields::named() - .field( - Field::named_of::>("right") - .with_type_display_name(vec!["Box"]), - ) - .field( - Field::named_of::>("left") - .with_type_display_name(vec!["Box"]), - ), + .field_of::>("right", "Box < Tree >") + .field_of::>("left", "Box < Tree >"), ), ); @@ -208,15 +177,9 @@ fn fields_with_type_alias() { a: BoolAlias, } - let ty = - Type::builder() - .path(Path::new("S", "derive")) - .composite( - Fields::named().field( - Field::named_of::("a") - .with_type_display_name(vec!["BoolAlias"]), - ), - ); + let ty = Type::builder() + .path(Path::new("S", "derive")) + .composite(Fields::named().field_of::("a", "BoolAlias")); assert_type!(S, ty); } diff --git a/test_suite/tests/json.rs b/test_suite/tests/json.rs index b90a6105..7bb51ee7 100644 --- a/test_suite/tests/json.rs +++ b/test_suite/tests/json.rs @@ -103,7 +103,7 @@ fn test_builtins() { }, { "name": "Some", - "fields": [ { "type": 1 } ] + "fields": [ { "type": 1, "typeName": "T" } ] }, ] } @@ -117,11 +117,11 @@ fn test_builtins() { "variants": [ { "name": "Ok", - "fields": [ { "type": 1 } ] + "fields": [ { "type": 1, "typeName": "T" } ] }, { "name": "Err", - "fields": [ { "type": 2 } ] + "fields": [ { "type": 2, "typeName": "E" } ] } ] } @@ -171,9 +171,9 @@ fn test_tuplestruct() { "def": { "composite": { "fields": [ - { "type": 1, "displayName": ["i32"] }, - { "type": 2 }, - { "type": 4, "displayName": ["bool"] }, + { "type": 1, "typeName": "i32" }, + { "type": 2, "typeName": "[u8 ; 32]" }, + { "type": 4, "typeName": "bool" }, ], }, } @@ -194,9 +194,9 @@ fn test_struct() { "def": { "composite": { "fields": [ - { "name": "a", "type": 1, "displayName": ["i32"] }, - { "name": "b", "type": 2 }, - { "name": "c", "type": 4, "displayName": ["bool"] }, + { "name": "a", "type": 1, "typeName": "i32" }, + { "name": "b", "type": 2, "typeName": "[u8 ; 32]" }, + { "name": "c", "type": 4, "typeName": "bool" }, ], }, } @@ -244,16 +244,16 @@ fn test_enum() { { "name": "TupleStructVariant", "fields": [ - { "type": 1, "displayName": ["u32"] }, - { "type": 2, "displayName": ["bool"] }, + { "type": 1, "typeName": "u32" }, + { "type": 2, "typeName": "bool" }, ], }, { "name": "StructVariant", "fields": [ - { "name": "a", "type": 1, "displayName": ["u32"] }, - { "name": "b", "type": 3 }, - { "name": "c", "type": 5, "displayName": ["char"] }, + { "name": "a", "type": 1, "typeName": "u32" }, + { "name": "b", "type": 3, "typeName": "[u8 ; 32]" }, + { "name": "c", "type": 5, "typeName": "char" }, ], } ], @@ -283,14 +283,14 @@ fn test_recursive_type_with_box() { { "name": "Leaf", "fields": [ - { "name": "value", "type": 2, "displayName": ["i32"] }, + { "name": "value", "type": 2, "typeName": "i32" }, ], }, { "name": "Node", "fields": [ - { "name": "right", "type": 1, "displayName": ["Box"] }, - { "name": "left", "type": 1, "displayName": ["Box"] }, + { "name": "right", "type": 1, "typeName": "Box < Tree >" }, + { "name": "left", "type": 1, "typeName": "Box < Tree >" }, ], } ], @@ -363,8 +363,8 @@ fn test_registry() { "def": { "composite": { "fields": [ - { "type": 3, "displayName": ["u8"] }, - { "type": 4, "displayName": ["u32"] }, + { "type": 3, "typeName": "u8" }, + { "type": 4, "typeName": "u32" }, ], }, } @@ -386,16 +386,17 @@ fn test_registry() { { "name": "a", "type": 3, - "displayName": ["u8"] + "typeName": "u8" }, { "name": "b", "type": 4, - "displayName": ["u32"] + "typeName": "u32" }, { "name": "c", - "type": 6, // [u8; 32] + "type": 6, + "typeName": "[u8 ; 32]" } ] }, @@ -419,8 +420,8 @@ fn test_registry() { "fields": [ { "name": "rec", - "type": 8, // Vec - "displayName": ["Vec"] + "type": 8, + "typeName": "Vec < RecursiveStruct >" } ] }, @@ -471,8 +472,8 @@ fn test_registry() { { "name": "B", "fields": [ - { "type": 3, "displayName": ["u8"] }, // u8 - { "type": 4, "displayName": ["u32"] }, // u32 + { "type": 3, "typeName": "u8" }, // u8 + { "type": 4, "typeName": "u32" }, // u32 ] }, { @@ -481,16 +482,17 @@ fn test_registry() { { "name": "a", "type": 3, // u8 - "displayName": ["u8"] + "typeName": "u8" }, { "name": "b", "type": 4, // u32 - "displayName": ["u32"] + "typeName": "u32" }, { "name": "c", - "type": 6, // [u8; 32] + "type": 6, + "typeName": "[u8 ; 32]" } ] } From c9873ce5d9d6cec472a7630ec2aa808eb6efa98a Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 26 Nov 2020 17:13:14 +0000 Subject: [PATCH 10/11] Clean up whitespace from type names --- derive/src/lib.rs | 30 +++++++++++++++++++++++++++--- test_suite/tests/derive.rs | 4 ++-- test_suite/tests/json.rs | 16 ++++++++-------- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 28746ebc..511c0bec 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -19,7 +19,13 @@ extern crate proc_macro; mod impl_wrapper; -use alloc::vec::Vec; +use alloc::{ + string::{ + String, + ToString, + }, + vec::Vec, +}; use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::quote; @@ -104,20 +110,38 @@ fn generate_fields(fields: &FieldsList) -> Vec { .iter() .map(|f| { let (ty, ident) = (&f.ty, &f.ident); + let type_name = clean_type_string("e!(#ty).to_string()); if let Some(i) = ident { quote! { - .field_of::<#ty>(stringify!(#i), stringify!(#ty)) + .field_of::<#ty>(stringify!(#i), #type_name) } } else { quote! { - .field_of::<#ty>(stringify!(#ty)) + .field_of::<#ty>(#type_name) } } }) .collect() } +fn clean_type_string(input: &str) -> String { + input + .replace(" ::", "::") + .replace(":: ", "::") + .replace(" ,", ",") + .replace(" ;", ";") + .replace(" [", "[") + .replace("[ ", "[") + .replace(" ]", "]") + .replace(" (", "(") + .replace("( ", "(") + .replace(" )", ")") + .replace(" <", "<") + .replace("< ", "<") + .replace(" >", ">") +} + fn generate_composite_type(data_struct: &DataStruct) -> TokenStream2 { let fields = match data_struct.fields { Fields::Named(ref fs) => { diff --git a/test_suite/tests/derive.rs b/test_suite/tests/derive.rs index 9f9fad16..ba7deede 100644 --- a/test_suite/tests/derive.rs +++ b/test_suite/tests/derive.rs @@ -159,8 +159,8 @@ fn recursive_type_derive() { .variant( "Node", Fields::named() - .field_of::>("right", "Box < Tree >") - .field_of::>("left", "Box < Tree >"), + .field_of::>("right", "Box") + .field_of::>("left", "Box"), ), ); diff --git a/test_suite/tests/json.rs b/test_suite/tests/json.rs index 7bb51ee7..7306d273 100644 --- a/test_suite/tests/json.rs +++ b/test_suite/tests/json.rs @@ -172,7 +172,7 @@ fn test_tuplestruct() { "composite": { "fields": [ { "type": 1, "typeName": "i32" }, - { "type": 2, "typeName": "[u8 ; 32]" }, + { "type": 2, "typeName": "[u8; 32]" }, { "type": 4, "typeName": "bool" }, ], }, @@ -195,7 +195,7 @@ fn test_struct() { "composite": { "fields": [ { "name": "a", "type": 1, "typeName": "i32" }, - { "name": "b", "type": 2, "typeName": "[u8 ; 32]" }, + { "name": "b", "type": 2, "typeName": "[u8; 32]" }, { "name": "c", "type": 4, "typeName": "bool" }, ], }, @@ -252,7 +252,7 @@ fn test_enum() { "name": "StructVariant", "fields": [ { "name": "a", "type": 1, "typeName": "u32" }, - { "name": "b", "type": 3, "typeName": "[u8 ; 32]" }, + { "name": "b", "type": 3, "typeName": "[u8; 32]" }, { "name": "c", "type": 5, "typeName": "char" }, ], } @@ -289,8 +289,8 @@ fn test_recursive_type_with_box() { { "name": "Node", "fields": [ - { "name": "right", "type": 1, "typeName": "Box < Tree >" }, - { "name": "left", "type": 1, "typeName": "Box < Tree >" }, + { "name": "right", "type": 1, "typeName": "Box" }, + { "name": "left", "type": 1, "typeName": "Box" }, ], } ], @@ -396,7 +396,7 @@ fn test_registry() { { "name": "c", "type": 6, - "typeName": "[u8 ; 32]" + "typeName": "[u8; 32]" } ] }, @@ -421,7 +421,7 @@ fn test_registry() { { "name": "rec", "type": 8, - "typeName": "Vec < RecursiveStruct >" + "typeName": "Vec" } ] }, @@ -492,7 +492,7 @@ fn test_registry() { { "name": "c", "type": 6, - "typeName": "[u8 ; 32]" + "typeName": "[u8; 32]" } ] } From 47ccdb00adfe44d5e0fe4495c0a2e4c7b336a9a7 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 30 Nov 2020 09:47:30 +0000 Subject: [PATCH 11/11] Add field comment --- src/ty/fields.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ty/fields.rs b/src/ty/fields.rs index c66df943..687f55d0 100644 --- a/src/ty/fields.rs +++ b/src/ty/fields.rs @@ -147,7 +147,11 @@ where &self.ty } - /// The name of the type of the field as it appears in the source code. + /// Returns a string which is the name of the type of the field as it + /// appears in the source code. The exact contents and format of the type + /// name are not specified, but in practice will be the name of any valid + /// type for a field. This is intended for informational and diagnostic + /// purposes only. pub fn type_name(&self) -> &T::String { &self.type_name }