1use crate::type_registry_set::TypeRegistrySet;
21use crate::type_shape::{Field, TypeShape, Variant, VariantDesc};
22use crate::{InsertName, LookupName, RuntimeApiInput, TypeRegistry};
23use alloc::borrow::{Cow, ToOwned};
24use alloc::format;
25use alloc::string::String;
26use alloc::vec;
27use alloc::vec::Vec;
28use hashbrown::HashMap;
29use serde::de::Deserialize;
30use serde::de::Error;
31
32#[derive(Debug, serde::Deserialize)]
152pub struct ChainTypeRegistry {
153 #[serde(skip, default = "TypeRegistry::basic")]
156 basics: TypeRegistry,
157 #[serde(deserialize_with = "deserialize_global")]
158 global: TypeRegistry,
159 #[serde(default, deserialize_with = "deserialize_for_spec", rename = "forSpec")]
160 for_spec: Vec<((u64, u64), TypeRegistry)>,
161}
162
163impl ChainTypeRegistry {
164 pub fn empty() -> Self {
167 ChainTypeRegistry {
168 basics: TypeRegistry::empty(),
169 global: TypeRegistry::empty(),
170 for_spec: Vec::new(),
171 }
172 }
173
174 pub fn for_spec_version(&self, spec_version: u64) -> TypeRegistrySet<'_> {
176 let basics = core::iter::once(&self.basics);
177 let globals = core::iter::once(&self.global);
178 let for_spec = self
179 .for_spec
180 .iter()
181 .filter(|((min, max), _)| spec_version >= *min && spec_version <= *max)
182 .map(|(_, types)| types);
183
184 let all = basics.chain(globals).chain(for_spec);
185 TypeRegistrySet::from_iter(all)
186 }
187
188 pub fn spec_version_ranges(&self) -> impl Iterator<Item = (u64, u64)> + use<'_> {
190 self.for_spec.iter().map(|(range, _)| *range)
191 }
192
193 pub fn extend(&mut self, other: ChainTypeRegistry) {
196 self.global.extend(other.global);
197 self.for_spec.extend(other.for_spec);
198 }
199}
200
201fn deserialize_global<'de, D: serde::Deserializer<'de>>(
205 deserializer: D,
206) -> Result<TypeRegistry, D::Error> {
207 let chain_types = DeserializableChainTypes::deserialize(deserializer)?;
208 Ok(chain_types.into_type_registry())
209}
210
211#[allow(clippy::type_complexity)]
212fn deserialize_for_spec<'de, D: serde::Deserializer<'de>>(
213 deserializer: D,
214) -> Result<Vec<((u64, u64), TypeRegistry)>, D::Error> {
215 let for_spec = <Vec<DeserializableChainTypesForSpec>>::deserialize(deserializer)?;
216 Ok(for_spec.into_iter().map(|s| (s.range, s.types.into_type_registry())).collect())
217}
218
219#[derive(serde::Deserialize, Default)]
221pub struct DeserializableChainTypes {
222 #[serde(default)]
223 types: HashMap<InsertName, DeserializableShape>,
224 #[serde(default, rename = "palletTypes")]
225 pallet_types: HashMap<String, HashMap<InsertName, DeserializableShape>>,
226 #[serde(default, rename = "runtimeApis")]
227 runtime_apis: HashMap<String, HashMap<String, DeserializableRuntimeApi>>,
228}
229
230impl DeserializableChainTypes {
231 fn into_type_registry(self) -> TypeRegistry {
233 let global_types = self.types.into_iter().map(|(k, v)| (k, v.into()));
234 let pallet_types = self.pallet_types.into_iter().flat_map(|(pallet, types)| {
235 types.into_iter().map(move |(k, v)| (k.in_pallet(pallet.clone()), v.into()))
236 });
237
238 let mut registry = TypeRegistry::from_iter(global_types.chain(pallet_types));
239
240 for (trait_name, methods) in self.runtime_apis {
242 for (method_name, api) in methods {
243 registry.insert_runtime_api(
244 trait_name.clone(),
245 method_name,
246 api.inputs.inputs,
247 api.output,
248 );
249 }
250 }
251
252 registry
253 }
254}
255
256#[derive(serde::Deserialize)]
258pub struct DeserializableChainTypesForSpec {
259 #[serde(deserialize_with = "deserialize_spec_range")]
260 range: (u64, u64),
261 #[serde(flatten)]
262 types: DeserializableChainTypes,
263}
264
265fn deserialize_spec_range<'de, D: serde::Deserializer<'de>>(
267 deserializer: D,
268) -> Result<(u64, u64), D::Error> {
269 let (min, max) = <(Option<u64>, Option<u64>)>::deserialize(deserializer)?;
270 Ok((min.unwrap_or(u64::MIN), max.unwrap_or(u64::MAX)))
271}
272
273#[derive(serde::Deserialize)]
275struct DeserializableRuntimeApi {
276 inputs: DeserializableRuntimeApiInputs,
277 output: LookupName,
278}
279
280struct DeserializableRuntimeApiInputs {
285 inputs: Vec<RuntimeApiInput>,
286}
287
288impl<'de> serde::Deserialize<'de> for DeserializableRuntimeApiInputs {
289 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
290 where
291 D: serde::Deserializer<'de>,
292 {
293 struct DeserializableShapeVisitor;
294 impl<'de> serde::de::Visitor<'de> for DeserializableShapeVisitor {
295 type Value = DeserializableRuntimeApiInputs;
296
297 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
298 formatter.write_str("a struct or array")
299 }
300
301 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
304 where
305 A: serde::de::MapAccess<'de>,
306 {
307 let mut inputs = vec![];
308 while let Some((name, id)) = map.next_entry::<String, LookupName>()? {
309 inputs.push(RuntimeApiInput { name, id })
310 }
311 Ok(DeserializableRuntimeApiInputs { inputs })
312 }
313
314 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
316 where
317 A: serde::de::SeqAccess<'de>,
318 {
319 let mut inputs = vec![];
320 while let Some(lookup_name) = seq.next_element::<LookupName>()? {
321 inputs.push(lookup_name.into())
322 }
323 Ok(DeserializableRuntimeApiInputs { inputs })
324 }
325
326 fn visit_unit<E>(self) -> Result<Self::Value, E>
328 where
329 E: Error,
330 {
331 Ok(DeserializableRuntimeApiInputs { inputs: vec![] })
332 }
333 }
334
335 deserializer.deserialize_any(DeserializableShapeVisitor)
336 }
337}
338
339#[allow(clippy::enum_variant_names)]
341#[derive(Debug)]
342#[cfg_attr(test, derive(PartialEq))]
343enum DeserializableShape {
344 AliasOf(LookupName),
345 NamedStructOf(Vec<Field>),
346 UnnamedStructOf(Vec<LookupName>),
347 EnumOf(Vec<Variant>),
348}
349
350impl From<DeserializableShape> for TypeShape {
351 fn from(value: DeserializableShape) -> Self {
352 match value {
353 DeserializableShape::AliasOf(a) => TypeShape::AliasOf(a),
354 DeserializableShape::NamedStructOf(a) => TypeShape::NamedStructOf(a),
355 DeserializableShape::EnumOf(a) => TypeShape::EnumOf(a),
356 DeserializableShape::UnnamedStructOf(a) => TypeShape::UnnamedStructOf(a),
357 }
358 }
359}
360
361impl<'de> serde::Deserialize<'de> for DeserializableShape {
362 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
363 where
364 D: serde::Deserializer<'de>,
365 {
366 struct DeserializableShapeVisitor;
367 impl<'de> serde::de::Visitor<'de> for DeserializableShapeVisitor {
368 type Value = DeserializableShape;
369
370 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
371 formatter.write_str("a string, struct or array")
372 }
373
374 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
376 where
377 E: serde::de::Error,
378 {
379 let name = LookupName::parse(v)
380 .map_err(|e| E::custom(format!("Could not deserialize into AliasOf: {e}")))?;
381 Ok(DeserializableShape::AliasOf(name))
382 }
383
384 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
386 where
387 A: serde::de::MapAccess<'de>,
388 {
389 let Some(name) = map.next_key::<String>()? else {
390 return Ok(DeserializableShape::NamedStructOf(Vec::new()));
392 };
393
394 if name == "_enum" {
396 let variants: DeserializableEnum = map.next_value()?;
397 return Ok(DeserializableShape::EnumOf(variants.0));
398 }
399
400 let mut fields = Vec::new();
403 fields.push(Field { name, value: map.next_value()? });
404
405 while let Some((name, value)) = map.next_entry()? {
406 fields.push(Field { name, value });
407 }
408
409 Ok(DeserializableShape::NamedStructOf(fields))
410 }
411
412 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
415 where
416 A: serde::de::SeqAccess<'de>,
417 {
418 let mut tuple_types = Vec::new();
419 while let Some(lookup_name) = seq.next_element()? {
420 tuple_types.push(lookup_name)
421 }
422 Ok(DeserializableShape::UnnamedStructOf(tuple_types))
423 }
424
425 fn visit_unit<E>(self) -> Result<Self::Value, E>
427 where
428 E: Error,
429 {
430 Ok(DeserializableShape::UnnamedStructOf(vec![]))
431 }
432 }
433
434 deserializer.deserialize_any(DeserializableShapeVisitor)
435 }
436}
437
438struct DeserializableEnum(Vec<Variant>);
439
440impl<'de> serde::Deserialize<'de> for DeserializableEnum {
441 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
442 where
443 D: serde::Deserializer<'de>,
444 {
445 struct DeserializableEnumVisitor;
446 impl<'de> serde::de::Visitor<'de> for DeserializableEnumVisitor {
447 type Value = DeserializableEnum;
448
449 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
450 formatter.write_str("a struct or array of enum variants")
451 }
452
453 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
454 where
455 A: serde::de::MapAccess<'de>,
456 {
457 let mut variants = Vec::new();
458 let mut index = 0;
459 while let Some((name, value)) =
460 map.next_entry::<String, DeserializableEnumFields>()?
461 {
462 variants.push(Variant { index, name, fields: value.0 });
463 index = index.saturating_add(1);
464 }
465 Ok(DeserializableEnum(variants))
466 }
467
468 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
469 where
470 A: serde::de::SeqAccess<'de>,
471 {
472 let mut variants = Vec::new();
473 let mut index = 0;
474 while let Some(field) = seq.next_element::<DeserializableEnumSeq>()? {
475 let variant = match field {
476 DeserializableEnumSeq::Name(name) => {
477 Variant { index, name, fields: VariantDesc::UnnamedStructOf(vec![]) }
478 }
479 DeserializableEnumSeq::Explicit(variant) => variant,
480 };
481 variants.push(variant);
482 index = index.saturating_add(1);
483 }
484 Ok(DeserializableEnum(variants))
485 }
486 }
487
488 deserializer.deserialize_any(DeserializableEnumVisitor)
489 }
490}
491
492struct DeserializableEnumFields(VariantDesc);
493
494impl<'de> serde::Deserialize<'de> for DeserializableEnumFields {
495 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
496 where
497 D: serde::Deserializer<'de>,
498 {
499 let variant_desc = match DeserializableShape::deserialize(deserializer)? {
500 DeserializableShape::AliasOf(lookup_name) => {
501 VariantDesc::UnnamedStructOf(vec![lookup_name])
502 }
503 DeserializableShape::NamedStructOf(fields) => VariantDesc::NamedStructOf(fields),
504 DeserializableShape::UnnamedStructOf(fields) => VariantDesc::UnnamedStructOf(fields),
505 DeserializableShape::EnumOf(_) => return Err(D::Error::custom("")),
506 };
507 Ok(DeserializableEnumFields(variant_desc))
508 }
509}
510
511enum DeserializableEnumSeq {
512 Name(String),
513 Explicit(Variant),
514}
515
516impl<'de> serde::Deserialize<'de> for DeserializableEnumSeq {
517 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
518 where
519 D: serde::Deserializer<'de>,
520 {
521 struct DeserializableEnumSeqVisitor;
522 impl<'de> serde::de::Visitor<'de> for DeserializableEnumSeqVisitor {
523 type Value = DeserializableEnumSeq;
524
525 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
526 formatter.write_str("a string representing a variant name, or a struct of variant name, index and fields")
527 }
528
529 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
530 where
531 E: Error,
532 {
533 Ok(DeserializableEnumSeq::Name(v))
534 }
535
536 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
537 where
538 E: Error,
539 {
540 self.visit_string(v.to_owned())
541 }
542
543 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
544 where
545 A: serde::de::MapAccess<'de>,
546 {
547 let mut index: Option<u8> = None;
548 let mut name: Option<String> = None;
549 let mut fields: Option<DeserializableEnumFields> = None;
550
551 while let Some(key) = map.next_key::<Cow<'de, str>>()? {
552 match &*key {
553 "index" => {
554 index = Some(map.next_value()?);
555 }
556 "name" => {
557 name = Some(map.next_value()?);
558 }
559 "fields" => {
560 fields = Some(map.next_value()?);
561 }
562 other => {
563 return Err(A::Error::custom(format!(
564 "field '{other}' not expected. Expecting 'index', 'name' or 'fields'"
565 )))
566 }
567 }
568 }
569
570 Ok(DeserializableEnumSeq::Explicit(Variant {
571 index: index.ok_or_else(|| A::Error::custom("field 'index' is missing"))?,
572 name: name.ok_or_else(|| A::Error::custom("field 'name' is missing"))?,
573 fields: fields
574 .unwrap_or(DeserializableEnumFields(VariantDesc::UnnamedStructOf(vec![])))
575 .0,
576 }))
577 }
578 }
579
580 deserializer.deserialize_any(DeserializableEnumSeqVisitor)
581 }
582}
583
584#[cfg(test)]
585mod test {
586 use super::*;
587 use crate::test_utils::{to_resolved_info, ResolvedTypeInfo};
588 use crate::LookupName;
589 use scale_type_resolver::Primitive;
590
591 fn ln(s: &str) -> LookupName {
592 LookupName::parse(s).unwrap()
593 }
594
595 #[test]
596 fn deserialize_spec_range_works() {
597 let cases = [
598 ("[12, 30]", (12, 30)),
599 ("[null, 30]", (u64::MIN, 30)),
600 ("[1000, null]", (1000, u64::MAX)),
601 ("[null, null]", (u64::MIN, u64::MAX)),
602 ];
603
604 for (range, expected) in cases {
605 let json = format!(r#"{{ "range": {range}, "types": {{}}, "palletTypes": {{}} }}"#);
606 let res = serde_json::from_str::<DeserializableChainTypesForSpec>(&json).unwrap();
607 assert_eq!(res.range, expected);
608 }
609 }
610
611 #[test]
612 fn deserializable_shape_enum_mixed_up_fails() {
613 let this_should_fail = r#"{ "_enum": ["One", "Two", "Three"], "foo": "u64" }"#;
615 let _ =
616 serde_json::from_str::<DeserializableShape>(this_should_fail).expect_err("should fail");
617 }
618
619 #[test]
620 fn deserializable_shape_works() {
621 let examples = [
622 (r#""Vec<T>""#, DeserializableShape::AliasOf(ln("Vec<T>"))),
624 (
626 r#"["Vec<T>", "bool"]"#,
627 DeserializableShape::UnnamedStructOf(vec![ln("Vec<T>"), ln("bool")]),
628 ),
629 (
631 r#"{ "a": "Vec<T>", "b": "bool" }"#,
632 DeserializableShape::NamedStructOf(vec![
633 Field { name: "a".to_owned(), value: ln("Vec<T>") },
634 Field { name: "b".to_owned(), value: ln("bool") },
635 ]),
636 ),
637 (
639 r#"{ "_enum": ["One", "Two", "Three"] }"#,
640 DeserializableShape::EnumOf(vec![
641 Variant {
642 index: 0,
643 name: "One".to_owned(),
644 fields: VariantDesc::UnnamedStructOf(vec![]),
645 },
646 Variant {
647 index: 1,
648 name: "Two".to_owned(),
649 fields: VariantDesc::UnnamedStructOf(vec![]),
650 },
651 Variant {
652 index: 2,
653 name: "Three".to_owned(),
654 fields: VariantDesc::UnnamedStructOf(vec![]),
655 },
656 ]),
657 ),
658 (
660 r#"{ "_enum": {"One": ["Vec<T>", "bool"], "Two": null, "Three": {"a": "Vec<T>", "b": "bool"} } }"#,
661 DeserializableShape::EnumOf(vec![
662 Variant {
663 index: 0,
664 name: "One".to_owned(),
665 fields: VariantDesc::UnnamedStructOf(vec![ln("Vec<T>"), ln("bool")]),
666 },
667 Variant {
668 index: 1,
669 name: "Two".to_owned(),
670 fields: VariantDesc::UnnamedStructOf(vec![]),
671 },
672 Variant {
673 index: 2,
674 name: "Three".to_owned(),
675 fields: VariantDesc::NamedStructOf(vec![
676 Field { name: "a".to_owned(), value: ln("Vec<T>") },
677 Field { name: "b".to_owned(), value: ln("bool") },
678 ]),
679 },
680 ]),
681 ),
682 (
684 r#"{ "_enum": [{ "name": "One", "index": 3, "fields": ["Vec<T>", "bool"] }] }"#,
685 DeserializableShape::EnumOf(vec![Variant {
686 index: 3,
687 name: "One".to_owned(),
688 fields: VariantDesc::UnnamedStructOf(vec![ln("Vec<T>"), ln("bool")]),
689 }]),
690 ),
691 ];
692
693 for (json, expected) in examples {
694 let actual: DeserializableShape =
695 serde_json::from_str(json).unwrap_or_else(|_| panic!("{json} should parse"));
696 assert_eq!(actual, expected);
697 }
698 }
699
700 #[test]
702 fn can_deserialize_from_json() {
703 let json = serde_json::json!({
704 "global": {
706 "types": {
708 "Foo": "u8",
710 "TupleOf": "(bool, Vec<String>)",
712 "UnnamedStructOf": ["bool", "Vec<String>"],
714 "StructOf<T>": {
716 "a": "bool",
717 "b": "T"
718 },
719 "EnumWithoutData": {
721 "_enum": ["One", "Two", "Three"]
722 },
723 "EnumWithData": {
725 "_enum": {
726 "A": "u64",
727 "B": ["bool", "char"],
728 "C": { "field_a": "String", "field_b": "bool" }
729 }
730 },
731 "EnumWithExplicitDetails": {
733 "_enum": [
734 { "name": "A", "index": 0, "fields": "u64" },
735 { "name": "B", "index": 1, "fields": ["bool", "char"] },
736 { "name": "C", "index": 2, "fields": { "field_a": "String", "field_b": "bool" } }
737 ]
738 }
739 },
740 "palletTypes": {
742 "balances": {
744 "Balance": "u64"
745 },
746 "assets": {
748 "Fee": "u32",
749 "AssetsEnum": {
750 "_enum": ["One", "Two", "Three"]
751 }
752 }
753 },
754 "runtimeApis": {
756 "Metadata": {
757 "foo": {
758 "inputs": { "a": "u32", "b": "bool", "c": "u16" },
760 "output": "Vec<u32>"
761 },
762 "bar": {
763 "inputs": null,
765 "output": "bool"
766 },
767 "metadata_at_version": {
768 "inputs": ["u32"],
770 "output": "Option<Vec<u8>>"
771 }
772 }
773 },
774 },
775 "forSpec": [
778 {
779 "range": [null, 1000],
781 "types": {
782 "Foo": "u64",
783 "UnnamedStructOf": ["bool", "Vec<String>"],
784 "StructOf<T>": { "a": "bool", "b": "T" },
785 },
786 "palletTypes": {
787 "balances": {
788 "Balance": "u128"
789 },
790 }
791 },
792 {
793 "range": [1001, 2000],
795 "types": {
796 "Foo": "String",
797 "UnnamedStructOf": ["bool", "Vec<String>"],
798 "StructOf<T>": { "a": "bool", "b": "T" },
799 },
800 "runtimeApis": {
801 "Metadata": {
802 "metadata_at_version": {
803 "inputs": ["u32"],
804 "output": "Foo"
805 }
806 }
807 },
808 }
809 ]
810 });
811
812 let tys: ChainTypeRegistry = serde_json::from_value(json).unwrap();
813
814 let resolver = tys.for_spec_version(12345);
815 assert_eq!(to_resolved_info("Foo", &resolver), ResolvedTypeInfo::Primitive(Primitive::U8));
816 assert_eq!(
817 to_resolved_info(ln("Balance").in_pallet("balances"), &resolver),
818 ResolvedTypeInfo::Primitive(Primitive::U64)
819 );
820
821 let runtime_api = resolver.runtime_api("Metadata", "foo").expect("Can find Runtime API");
823 assert_eq!(
824 &runtime_api.inputs,
825 &[
826 RuntimeApiInput { name: "a".into(), id: ln("u32") },
827 RuntimeApiInput { name: "b".into(), id: ln("bool") },
828 RuntimeApiInput { name: "c".into(), id: ln("u16") },
829 ]
830 );
831 assert_eq!(&runtime_api.output, &ln("Vec<u32>"));
832
833 let runtime_api = resolver.runtime_api("Metadata", "bar").expect("Can find Runtime API");
835 assert_eq!(&runtime_api.inputs, &[]);
836 assert_eq!(&runtime_api.output, &ln("bool"));
837
838 let runtime_api =
840 resolver.runtime_api("Metadata", "metadata_at_version").expect("Can find Runtime API");
841 assert_eq!(&runtime_api.inputs, &[RuntimeApiInput { name: "".into(), id: ln("u32") }]);
842 assert_eq!(&runtime_api.output, &ln("Option<Vec<u8>>"));
843
844 let resolver = tys.for_spec_version(500);
845 assert_eq!(to_resolved_info("Foo", &resolver), ResolvedTypeInfo::Primitive(Primitive::U64));
846 assert_eq!(
847 to_resolved_info(ln("Balance").in_pallet("balances"), &resolver),
848 ResolvedTypeInfo::Primitive(Primitive::U128)
849 );
850
851 let runtime_api =
852 resolver.runtime_api("Metadata", "metadata_at_version").expect("Can find Runtime API");
853 assert_eq!(&runtime_api.inputs, &[ln("u32").into()]);
854 assert_eq!(&runtime_api.output, &ln("Option<Vec<u8>>"));
855
856 let resolver = tys.for_spec_version(2000);
857 assert_eq!(to_resolved_info("Foo", &resolver), ResolvedTypeInfo::Primitive(Primitive::Str));
858
859 let runtime_api =
860 resolver.runtime_api("Metadata", "metadata_at_version").expect("Can find Runtime API");
861 assert_eq!(&runtime_api.inputs, &[ln("u32").into()]);
862 assert_eq!(&runtime_api.output, &ln("Foo"));
863 }
864}