1#![cfg_attr(not(feature = "std"), no_std)]
2#[macro_use]
7extern crate alloc;
8
9#[cfg(feature = "experimental-serializer")]
10mod serializer;
11mod value;
12
13pub use bytes::Bytes;
14#[cfg(feature = "json")]
15pub use serde_json::Value as JsonValue;
16#[cfg(feature = "experimental-serializer")]
17pub use serializer::{to_bytes, to_bytes_with_info, to_vec, to_vec_with_info, Serializer};
18pub use value::Value;
19
20use prelude::*;
21use scale_info::{form::PortableForm as Portable, PortableRegistry};
22
23mod prelude {
24 pub use alloc::{
25 collections::BTreeMap,
26 string::{String, ToString},
27 vec::Vec,
28 };
29 pub use core::ops::Deref;
30}
31
32type Type = scale_info::Type<Portable>;
33type Field = scale_info::Field<Portable>;
34type Variant = scale_info::Variant<Portable>;
35type TypeId = u32;
36
37macro_rules! is_tuple {
38 ($it:ident) => {
39 $it.fields().first().and_then(Field::name).is_none()
40 };
41}
42
43#[rustfmt::skip]
46#[derive(Debug, Clone, serde::Serialize)]
47#[cfg_attr(feature = "codec", derive(codec::Encode))]
48pub enum SpecificType {
49 Bool,
50 U8, U16, U32, U64, U128,
51 I8, I16, I32, I64, I128,
52 Bytes,
53 Char,
54 Str,
55 Sequence(TypeId),
56 Map(TypeId, TypeId),
57 Tuple(TupleOrArray),
58 Struct(Vec<(String, TypeId)>), StructUnit, StructNewType(TypeId), StructTuple(Vec<TypeId>),
59 Variant(String, Vec<Variant>, Option<u8>),
60}
61
62impl From<(&Type, &PortableRegistry)> for SpecificType {
63 fn from((ty, registry): (&Type, &PortableRegistry)) -> Self {
64 use scale_info::{TypeDef, TypeDefComposite, TypeDefPrimitive};
65 type Def = TypeDef<Portable>;
66
67 macro_rules! resolve {
68 ($ty:expr) => {
69 registry.resolve($ty.id()).unwrap()
70 };
71 }
72 let is_map = |ty: &Type| -> bool { ty.path().segments() == ["BTreeMap"] };
73 let map_types = |ty: &TypeDefComposite<Portable>| -> (TypeId, TypeId) {
74 let field = ty.fields().first().expect("map");
75 if let Def::Sequence(s) = resolve!(field.ty()).type_def() {
77 if let Def::Tuple(t) = resolve!(s.type_param()).type_def() {
78 assert_eq!(t.fields().len(), 2);
79 let key_ty = t.fields().first().expect("key").id();
80 let val_ty = t.fields().last().expect("val").id();
81 return (key_ty, val_ty);
82 }
83 }
84 unreachable!()
85 };
86
87 let name = ty
88 .path()
89 .segments()
90 .last()
91 .cloned()
92 .unwrap_or_else(|| "".into());
93
94 match ty.type_def() {
95 Def::Composite(c) => {
96 let fields = c.fields();
97 if fields.is_empty() {
98 Self::StructUnit
99 } else if is_map(ty) {
100 let (k, v) = map_types(c);
101 Self::Map(k, v)
102 } else if fields.len() == 1 && fields.first().unwrap().name().is_none() {
103 Self::StructNewType(fields.first().unwrap().ty().id())
104 } else if is_tuple!(c) {
105 Self::StructTuple(fields.iter().map(|f| f.ty().id()).collect())
106 } else {
107 Self::Struct(
108 fields
109 .iter()
110 .map(|f| (f.name().unwrap().deref().into(), f.ty().id()))
111 .collect(),
112 )
113 }
114 }
115 Def::Variant(v) => Self::Variant(name.into(), v.variants().into(), None),
116 Def::Sequence(s) => {
117 let ty = resolve!(s.type_param());
118 if ty.path().segments() != ["u8"] {
119 Self::Sequence(s.type_param().id())
120 } else {
121 Self::Bytes
122 }
123 }
124 Def::Array(a) => Self::Tuple(TupleOrArray::Array(a.type_param().id(), a.len())),
125 Def::Tuple(t) => Self::Tuple(TupleOrArray::Tuple(
126 t.fields().iter().map(|ty| ty.id()).collect(),
127 )),
128 Def::Primitive(p) => match p {
129 TypeDefPrimitive::U8 => Self::U8,
130 TypeDefPrimitive::U16 => Self::U16,
131 TypeDefPrimitive::U32 => Self::U32,
132 TypeDefPrimitive::U64 => Self::U64,
133 TypeDefPrimitive::U128 => Self::U128,
134 TypeDefPrimitive::I8 => Self::I8,
135 TypeDefPrimitive::I16 => Self::I16,
136 TypeDefPrimitive::I32 => Self::I32,
137 TypeDefPrimitive::I64 => Self::I64,
138 TypeDefPrimitive::I128 => Self::I128,
139 TypeDefPrimitive::Bool => Self::Bool,
140 TypeDefPrimitive::Str => Self::Str,
141 TypeDefPrimitive::Char => Self::Char,
142 TypeDefPrimitive::U256 => unimplemented!(),
143 TypeDefPrimitive::I256 => unimplemented!(),
144 },
145 Def::Compact(_c) => todo!(),
146 Def::BitSequence(_b) => todo!(),
147 }
148 }
149}
150
151impl SpecificType {
153 fn pick(&self, index: u8) -> Self {
154 match self {
155 SpecificType::Variant(name, variant, Some(_)) => {
156 Self::Variant(name.to_string(), variant.to_vec(), Some(index))
157 }
158 SpecificType::Variant(name, variants, None) => {
159 let v = variants.iter().find(|v| v.index() == index).unwrap();
160 Self::Variant(name.clone(), vec![v.clone()], Some(index))
161 }
162 _ => panic!("Only for enum variants"),
163 }
164 }
165
166 #[cfg(feature = "experimental-serializer")]
167 fn pick_mut<F, A, B>(&mut self, selection: A, get_field: F) -> &Self
168 where
169 F: Fn(&Variant) -> B,
170 A: AsRef<[u8]> + PartialEq + core::fmt::Debug,
171 B: AsRef<[u8]> + PartialEq + core::fmt::Debug,
172 {
173 match self {
174 SpecificType::Variant(_, _, Some(_)) => self,
175 SpecificType::Variant(_, ref mut variants, idx @ None) => {
176 let i = variants
177 .iter()
178 .map(|v| get_field(v))
179 .position(|f| f.as_ref() == selection.as_ref())
180 .expect("index") as u8;
181 variants.retain(|v| v.index() == i);
182 *idx = Some(i);
183 self
184 }
185 _ => panic!("Only for enum variants"),
186 }
187 }
188
189 #[cfg(feature = "experimental-serializer")]
190 fn variant_id(&self) -> u8 {
191 match self {
192 SpecificType::Variant(_, _, Some(id)) => *id,
193 _ => panic!("Only for enum variants"),
194 }
195 }
196}
197
198#[derive(Debug)]
199enum EnumVariant<'a> {
200 OptionNone,
201 OptionSome(TypeId),
202 Unit(u8, &'a str),
203 NewType(u8, &'a str, TypeId),
204 Tuple(u8, &'a str, Vec<TypeId>),
205 Struct(u8, &'a str, Vec<(&'a str, TypeId)>),
206}
207
208impl<'a> From<&'a SpecificType> for EnumVariant<'a> {
209 fn from(ty: &'a SpecificType) -> Self {
210 match ty {
211 SpecificType::Variant(name, variants, Some(idx)) => {
212 let variant = variants.first().expect("single variant");
213 let fields = variant.fields();
214 let vname = variant.name().as_ref();
215
216 if fields.is_empty() {
217 if name == "Option" && vname == "None" {
218 Self::OptionNone
219 } else {
220 Self::Unit(*idx, &vname)
221 }
222 } else if is_tuple!(variant) {
223 if fields.len() == 1 {
224 let ty = fields.first().map(|f| f.ty().id()).unwrap();
225 return if name == "Option" && variant.name() == &"Some" {
226 Self::OptionSome(ty)
227 } else {
228 Self::NewType(*idx, &vname, ty)
229 };
230 } else {
231 let fields = fields.iter().map(|f| f.ty().id()).collect();
232 Self::Tuple(*idx, &vname, fields)
233 }
234 } else {
235 let fields = fields
236 .iter()
237 .map(|f| (f.name().unwrap().deref(), f.ty().id()))
238 .collect();
239 Self::Struct(*idx, &vname, fields)
240 }
241 }
242 _ => panic!("Only for enum variants"),
243 }
244 }
245}
246
247#[derive(Debug, Clone, serde::Serialize)]
248#[cfg_attr(feature = "codec", derive(codec::Encode))]
249pub enum TupleOrArray {
250 Array(TypeId, u32),
251 Tuple(Vec<TypeId>),
252}
253impl TupleOrArray {
254 fn len(&self) -> usize {
255 match self {
256 Self::Array(_, len) => *len as usize,
257 Self::Tuple(fields) => fields.len(),
258 }
259 }
260
261 fn type_id(&self, i: usize) -> TypeId {
262 match self {
263 Self::Array(ty, _) => *ty,
264 Self::Tuple(fields) => fields[i],
265 }
266 }
267}