|
@@ -194,7 +194,7 @@ pub fn parse(
|
|
|
};
|
|
|
IdlEventField {
|
|
|
name: f.ident.clone().unwrap().to_string().to_mixed_case(),
|
|
|
- ty: parser::tts_to_string(&f.ty).parse().unwrap(),
|
|
|
+ ty: to_idl_type(&ctx, f),
|
|
|
index,
|
|
|
}
|
|
|
})
|
|
@@ -409,16 +409,9 @@ fn parse_ty_defs(ctx: &CrateContext) -> Result<Vec<IdlTypeDefinition>> {
|
|
|
.named
|
|
|
.iter()
|
|
|
.map(|f: &syn::Field| {
|
|
|
- let mut tts = proc_macro2::TokenStream::new();
|
|
|
- f.ty.to_tokens(&mut tts);
|
|
|
- // Handle array sizes that are constants
|
|
|
- let mut tts_string = tts.to_string();
|
|
|
- if tts_string.starts_with('[') {
|
|
|
- tts_string = resolve_variable_array_length(ctx, tts_string);
|
|
|
- }
|
|
|
Ok(IdlField {
|
|
|
name: f.ident.as_ref().unwrap().to_string().to_mixed_case(),
|
|
|
- ty: tts_string.parse()?,
|
|
|
+ ty: to_idl_type(ctx, f),
|
|
|
})
|
|
|
})
|
|
|
.collect::<Result<Vec<IdlField>>>(),
|
|
@@ -442,7 +435,7 @@ fn parse_ty_defs(ctx: &CrateContext) -> Result<Vec<IdlTypeDefinition>> {
|
|
|
syn::Fields::Unit => None,
|
|
|
syn::Fields::Unnamed(fields) => {
|
|
|
let fields: Vec<IdlType> =
|
|
|
- fields.unnamed.iter().map(to_idl_type).collect();
|
|
|
+ fields.unnamed.iter().map(|f| to_idl_type(ctx, f)).collect();
|
|
|
Some(EnumFields::Tuple(fields))
|
|
|
}
|
|
|
syn::Fields::Named(fields) => {
|
|
@@ -451,7 +444,7 @@ fn parse_ty_defs(ctx: &CrateContext) -> Result<Vec<IdlTypeDefinition>> {
|
|
|
.iter()
|
|
|
.map(|f: &syn::Field| {
|
|
|
let name = f.ident.as_ref().unwrap().to_string();
|
|
|
- let ty = to_idl_type(f);
|
|
|
+ let ty = to_idl_type(ctx, f);
|
|
|
IdlField { name, ty }
|
|
|
})
|
|
|
.collect();
|
|
@@ -470,11 +463,42 @@ fn parse_ty_defs(ctx: &CrateContext) -> Result<Vec<IdlTypeDefinition>> {
|
|
|
}
|
|
|
|
|
|
// Replace variable array lengths with values
|
|
|
-fn resolve_variable_array_length(ctx: &CrateContext, tts_string: String) -> String {
|
|
|
- for constant in ctx.consts() {
|
|
|
- if constant.ty.to_token_stream().to_string() == "usize"
|
|
|
- && tts_string.contains(&constant.ident.to_string())
|
|
|
- {
|
|
|
+fn resolve_variable_array_lengths(ctx: &CrateContext, mut tts_string: String) -> String {
|
|
|
+ for constant in ctx.consts().filter(|c| match *c.ty {
|
|
|
+ // Filter to only those consts that are of type usize or could be cast to usize
|
|
|
+ syn::Type::Path(ref p) => {
|
|
|
+ let segment = p.path.segments.last().unwrap();
|
|
|
+ matches!(
|
|
|
+ segment.ident.to_string().as_str(),
|
|
|
+ "usize"
|
|
|
+ | "u8"
|
|
|
+ | "u16"
|
|
|
+ | "u32"
|
|
|
+ | "u64"
|
|
|
+ | "u128"
|
|
|
+ | "isize"
|
|
|
+ | "i8"
|
|
|
+ | "i16"
|
|
|
+ | "i32"
|
|
|
+ | "i64"
|
|
|
+ | "i128"
|
|
|
+ )
|
|
|
+ }
|
|
|
+ _ => false,
|
|
|
+ }) {
|
|
|
+ let mut check_string = tts_string.clone();
|
|
|
+ // Strip whitespace to handle accidental double whitespaces
|
|
|
+ check_string.retain(|c| !c.is_whitespace());
|
|
|
+ let size_string = format!("{}]", &constant.ident.to_string());
|
|
|
+ let cast_size_string = format!("{}asusize]", &constant.ident.to_string());
|
|
|
+ // Check for something to replace
|
|
|
+ let mut replacement_string = None;
|
|
|
+ if check_string.contains(cast_size_string.as_str()) {
|
|
|
+ replacement_string = Some(cast_size_string);
|
|
|
+ } else if check_string.contains(size_string.as_str()) {
|
|
|
+ replacement_string = Some(size_string);
|
|
|
+ }
|
|
|
+ if let Some(replacement_string) = replacement_string {
|
|
|
// Check for the existence of consts existing elsewhere in the
|
|
|
// crate which have the same name, are usize, and have a
|
|
|
// different value. We can't know which was intended for the
|
|
@@ -487,19 +511,23 @@ fn resolve_variable_array_length(ctx: &CrateContext, tts_string: String) -> Stri
|
|
|
}) {
|
|
|
panic!("Crate wide unique name required for array size const.");
|
|
|
}
|
|
|
- return tts_string.replace(
|
|
|
- &constant.ident.to_string(),
|
|
|
- &constant.expr.to_token_stream().to_string(),
|
|
|
+ // Replace the match, don't break because there might be multiple replacements to be
|
|
|
+ // made in the case of multidimensional arrays
|
|
|
+ tts_string = check_string.replace(
|
|
|
+ &replacement_string,
|
|
|
+ format!("{}]", &constant.expr.to_token_stream()).as_str(),
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
tts_string
|
|
|
}
|
|
|
|
|
|
-fn to_idl_type(f: &syn::Field) -> IdlType {
|
|
|
- let mut tts = proc_macro2::TokenStream::new();
|
|
|
- f.ty.to_tokens(&mut tts);
|
|
|
- tts.to_string().parse().unwrap()
|
|
|
+fn to_idl_type(ctx: &CrateContext, f: &syn::Field) -> IdlType {
|
|
|
+ let mut tts_string = parser::tts_to_string(&f.ty);
|
|
|
+ if tts_string.starts_with('[') {
|
|
|
+ tts_string = resolve_variable_array_lengths(ctx, tts_string);
|
|
|
+ }
|
|
|
+ tts_string.parse().unwrap()
|
|
|
}
|
|
|
|
|
|
fn idl_accounts(
|