diff --git a/xtask/src/gen_doc.rs b/xtask/src/gen_doc.rs index b28d00692141d5e7b1fd04745eee1aa55170a87b..eb5dc2d8145a80a6d17a626b04dc89b39632a8e3 100644 --- a/xtask/src/gen_doc.rs +++ b/xtask/src/gen_doc.rs @@ -440,67 +440,96 @@ fn get_max_weight_from_metadata_v15( } } -fn format_type(ty: &Type<PortableForm>, types: &PortableRegistry) -> String { +fn format_type(ty: &Type<PortableForm>, types: &PortableRegistry) -> Result<String> { let path = ty.path.to_string(); match &ty.type_def { TypeDef::Composite(_) => { - let generics = format_generics(&ty.type_params, types); - format!("{}{}", path, generics) + let generics = format_generics(&ty.type_params, types)?; + Ok(format!("{}{}", path, generics)) } TypeDef::Variant(_) => { - let generics = format_generics(&ty.type_params, types); - format!("{}{}", path, generics) + let generics = format_generics(&ty.type_params, types)?; + Ok(format!("{}{}", path, generics)) } TypeDef::Sequence(seq) => { - let element_type = resolve_type(seq.type_param.id, types); - format!("Vec<{}>", element_type) + let element_type = resolve_type(seq.type_param.id, types)?; + Ok(format!("Vec<{}>", element_type)) } TypeDef::Array(arr) => { - let element_type = resolve_type(arr.type_param.id, types); - format!("[{}; {}]", element_type, arr.len) + let element_type = resolve_type(arr.type_param.id, types)?; + Ok(format!("[{}; {}]", element_type, arr.len)) } TypeDef::Tuple(tuple) => { - let elements: Vec<String> = tuple + let elements = tuple .fields .iter() .map(|f| resolve_type(f.id, types)) - .collect(); - format!("({})", elements.join(", ")) - } - TypeDef::Primitive(primitive) => { - format!("{:?}", primitive) + .collect::<Result<Vec<String>>>()?; + Ok(format!("({})", elements.join(", "))) } + TypeDef::Primitive(primitive) => Ok(format!("{:?}", primitive)), TypeDef::Compact(compact) => { - let inner_type = resolve_type(compact.type_param.id, types); - format!("Compact<{}>", inner_type) + let inner_type = resolve_type(compact.type_param.id, types)?; + Ok(format!("Compact<{}>", inner_type)) } - TypeDef::BitSequence(_) => "".to_string(), + TypeDef::BitSequence(_) => Ok(String::default()), } } -fn resolve_type(type_id: u32, types: &PortableRegistry) -> String { +fn resolve_type(type_id: u32, types: &PortableRegistry) -> Result<String> { types .resolve(type_id) .map(|t| format_type(t, types)) - .unwrap_or_else(|| "Unknown".to_string()) + .unwrap_or_else(|| bail!("Invalid metadata")) } fn format_generics( params: &[scale_info::TypeParameter<PortableForm>], types: &PortableRegistry, -) -> String { +) -> Result<String> { if params.is_empty() { - "".to_string() + Ok(String::default()) } else { - let generics: Vec<String> = params + let generics = params .iter() .map(|p| { p.ty.map(|ty| resolve_type(ty.id, types)) - .unwrap_or_default() + .unwrap_or_else(|| Ok(String::default())) }) - .collect(); - format!("<{}>", generics.join(", ")) + .collect::<Result<Vec<String>>>()?; + Ok(format!("<{}>", generics.join(", "))) + } +} +fn parse_storage_entry( + variant: &frame_metadata::v15::StorageEntryMetadata<scale_info::form::PortableForm>, + types: &PortableRegistry, +) -> Result<Storage> { + match &variant.ty { + StorageEntryType::Map { key, value, .. } => { + let type_key = resolve_type(key.id, types)?; + let type_value = resolve_type(value.id, types)?; + Ok(Storage { + documentation: variant.docs.join("\n"), + name: variant.name.clone(), + type_key, + type_value, + }) + } + StorageEntryType::Plain(v) => { + let type_value = resolve_type(v.id, types)?; + let type_value = if let StorageEntryModifier::Optional = &variant.modifier { + format!("Option<{}>", type_value) + } else { + type_value + }; + Ok(Storage { + documentation: variant.docs.join("\n"), + name: variant.name.clone(), + type_key: String::default(), + type_value, + }) + } } } @@ -545,71 +574,39 @@ fn get_from_metadata_v15( None }; - let storages: Vec<Storage> = pallet + let storages = pallet .storage .map(|storage| { storage .entries .iter() - .map(|variant| { - let resolve_type = |type_id: u32| -> String { - metadata_v15 - .types - .resolve(type_id) - .map(|resolved| format_type(resolved, &metadata_v15.types)) - .unwrap_or_default() - }; - match &variant.ty { - StorageEntryType::Map { key, value, .. } => Storage { - documentation: variant.docs.join("\n"), - name: variant.name.clone(), - type_key: resolve_type(key.id), - type_value: resolve_type(value.id), - }, - StorageEntryType::Plain(v) => Storage { - documentation: variant.docs.join("\n"), - name: variant.name.clone(), - type_key: String::default(), - type_value: if let StorageEntryModifier::Optional = - &variant.modifier - { - format!("Option<{}>", resolve_type(v.id)) - } else { - resolve_type(v.id) - }, - }, - } - }) - .collect() + .map(|v| parse_storage_entry(v, &metadata_v15.types)) + .collect::<Result<Vec<Storage>>>() }) - .unwrap_or_default(); + .unwrap_or_else(|| { + println!("{}: {} (0 storage)", pallet.index, pallet.name); + Ok(Vec::default()) + })?; - let constants: Vec<Constant> = pallet + let constants = pallet .constants .iter() .map(|i| { - let resolve_type = |type_id: u32| -> String { - metadata_v15 - .types - .resolve(type_id) - .map(|resolved| format_type(resolved, &metadata_v15.types)) - .unwrap_or_default() - }; - - let decode_value = |value: &Vec<u8>, type_id: u32| -> String { - scale_value::scale::decode_as_type(&mut &**value, &type_id, &metadata_v15.types) - .map(|v| v.to_string()) - .unwrap_or_default() - }; - - Constant { + let type_value = resolve_type(i.ty.id, &metadata_v15.types)?; + let value = scale_value::scale::decode_as_type( + &mut &*i.value, + &i.ty.id, + &metadata_v15.types, + ) + .map_err(|e| anyhow::anyhow!("{}", e))?; + Ok(Constant { documentation: i.docs.join("\n"), name: i.name.clone(), - value: decode_value(&i.value, i.ty.id), - type_value: resolve_type(i.ty.id), - } + value: value.to_string(), + type_value, + }) }) - .collect(); + .collect::<Result<Vec<Constant>>>()?; let pallet = Pallet::new( pallet.index,