1use crate::{EnumVariant, SpecificType};
2use alloc::{collections::BTreeMap, vec::Vec};
3use bytes::{Buf, Bytes};
4use core::{convert::TryInto, str};
5use scale_info::{prelude::*, PortableRegistry, TypeDefPrimitive as Primitive};
6use serde::ser::{SerializeMap, SerializeSeq, SerializeTuple, SerializeTupleStruct};
7use serde::Serialize;
8
9type Type = scale_info::Type<scale_info::form::PortableForm>;
10type TypeId = u32;
11type TypeDef = scale_info::TypeDef<scale_info::form::PortableForm>;
12
13pub struct Value<'a> {
16 data: Bytes,
17 ty_id: TypeId,
18 registry: &'a PortableRegistry,
19}
20
21impl<'a> Value<'a> {
22 pub fn new(data: impl Into<Bytes>, ty_id: u32, registry: &'a PortableRegistry) -> Self {
23 Value {
24 data: data.into(),
25 ty_id,
26 registry,
27 }
28 }
29
30 fn new_value(&self, data: &mut Bytes, ty_id: TypeId) -> Self {
31 let size = self.ty_len(data.chunk(), ty_id);
32 Value::new(data.copy_to_bytes(size), ty_id, self.registry)
33 }
34
35 #[inline]
36 fn resolve(&self, ty: TypeId) -> &'a Type {
37 self.registry.resolve(ty).expect("in registry")
38 }
39
40 fn ty_len(&self, data: &[u8], ty: TypeId) -> usize {
41 match self.resolve(ty).type_def() {
42 TypeDef::Primitive(p) => match p {
43 Primitive::U8 => mem::size_of::<u8>(),
44 Primitive::U16 => mem::size_of::<u16>(),
45 Primitive::U32 => mem::size_of::<u32>(),
46 Primitive::U64 => mem::size_of::<u64>(),
47 Primitive::U128 => mem::size_of::<u128>(),
48 Primitive::I8 => mem::size_of::<i8>(),
49 Primitive::I16 => mem::size_of::<i16>(),
50 Primitive::I32 => mem::size_of::<i32>(),
51 Primitive::I64 => mem::size_of::<i64>(),
52 Primitive::I128 => mem::size_of::<i128>(),
53 Primitive::Bool => mem::size_of::<bool>(),
54 Primitive::Char => mem::size_of::<char>(),
55 Primitive::Str => {
56 let (l, p_size) = sequence_len(data);
57 l + p_size
58 }
59 _ => unimplemented!(),
60 },
61 TypeDef::Composite(c) => c
62 .fields()
63 .iter()
64 .fold(0, |c, f| c + self.ty_len(&data[c..], f.ty().id())),
65 TypeDef::Variant(e) => {
66 let var = e
67 .variants()
68 .iter()
69 .find(|v| v.index() == data[0])
70 .expect("variant");
71
72 if var.fields().is_empty() {
73 1 } else {
75 var.fields()
76 .iter()
77 .fold(1, |c, f| c + self.ty_len(&data[c..], f.ty().id()))
78 }
79 }
80 TypeDef::Sequence(s) => {
81 let (len, prefix_size) = sequence_len(data);
82 let ty_id = s.type_param().id();
83 (0..len).fold(prefix_size, |c, _| c + self.ty_len(&data[c..], ty_id))
84 }
85 TypeDef::Array(a) => a.len().try_into().unwrap(),
86 TypeDef::Tuple(t) => t.fields().len(),
87 TypeDef::Compact(_) => compact_len(data),
88 TypeDef::BitSequence(_) => unimplemented!(),
89 }
90 }
91}
92
93impl<'a> Serialize for Value<'a> {
94 fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
95 where
96 S: serde::Serializer,
97 {
98 let mut data = self.data.clone();
99 let ty = self.resolve(self.ty_id);
100
101 use SpecificType::*;
102 match (ty, self.registry).into() {
103 Bool => ser.serialize_bool(data.get_u8() != 0),
104 U8 => ser.serialize_u8(data.get_u8()),
105 U16 => ser.serialize_u16(data.get_u16_le()),
106 U32 => ser.serialize_u32(data.get_u32_le()),
107 U64 => ser.serialize_u64(data.get_u64_le()),
108 U128 => ser.serialize_u128(data.get_u128_le()),
109 I8 => ser.serialize_i8(data.get_i8()),
110 I16 => ser.serialize_i16(data.get_i16_le()),
111 I32 => ser.serialize_i32(data.get_i32_le()),
112 I64 => ser.serialize_i64(data.get_i64_le()),
113 I128 => ser.serialize_i128(data.get_i128_le()),
114 Bytes => ser.serialize_bytes(data.chunk()),
115 Char => ser.serialize_char(char::from_u32(data.get_u32_le()).unwrap()),
116 Str => {
117 let (_, s) = sequence_len(data.chunk());
118 data.advance(s);
119 ser.serialize_str(str::from_utf8(data.chunk()).unwrap())
120 }
121 Sequence(ty) => {
122 let (len, p_size) = sequence_len(data.chunk());
123 data.advance(p_size);
124
125 let mut seq = ser.serialize_seq(Some(len))?;
126 for _ in 0..len {
127 seq.serialize_element(&self.new_value(&mut data, ty))?;
128 }
129 seq.end()
130 }
131 Map(ty_k, ty_v) => {
132 let (len, p_size) = sequence_len(data.chunk());
133 data.advance(p_size);
134
135 let mut state = ser.serialize_map(Some(len))?;
136 for _ in 0..len {
137 let key = self.new_value(&mut data, ty_k);
138 let val = self.new_value(&mut data, ty_v);
139 state.serialize_entry(&key, &val)?;
140 }
141 state.end()
142 }
143 Tuple(t) => {
144 let mut state = ser.serialize_tuple(t.len())?;
145 for i in 0..t.len() {
146 state.serialize_element(&self.new_value(&mut data, t.type_id(i)))?;
147 }
148 state.end()
149 }
150 Struct(fields) => {
151 let mut state = ser.serialize_map(Some(fields.len()))?;
152 for (name, ty) in fields {
153 state.serialize_key(&name)?;
154 state.serialize_value(&self.new_value(&mut data, ty))?;
155 }
156 state.end()
157 }
158 StructUnit => ser.serialize_unit(),
159 StructNewType(ty) => ser.serialize_newtype_struct("", &self.new_value(&mut data, ty)),
160 StructTuple(fields) => {
161 let mut state = ser.serialize_tuple_struct("", fields.len())?;
162 for ty in fields {
163 state.serialize_field(&self.new_value(&mut data, ty))?;
164 }
165 state.end()
166 }
167 ty @ Variant(_, _, _) => {
168 let variant = &ty.pick(data.get_u8());
169 match variant.into() {
170 EnumVariant::OptionNone => ser.serialize_none(),
171 EnumVariant::OptionSome(ty) => {
172 ser.serialize_some(&self.new_value(&mut data, ty))
173 }
174 EnumVariant::Unit(_idx, name) => ser.serialize_str(name),
175 EnumVariant::NewType(_idx, name, ty) => {
176 let mut s = ser.serialize_map(Some(1))?;
177 s.serialize_key(name)?;
178 s.serialize_value(&self.new_value(&mut data, ty))?;
179 s.end()
180 }
181
182 EnumVariant::Tuple(_idx, name, fields) => {
183 let mut s = ser.serialize_map(Some(1))?;
184 s.serialize_key(name)?;
185 s.serialize_value(
186 &fields
187 .iter()
188 .map(|ty| self.new_value(&mut data, *ty))
189 .collect::<Vec<_>>(),
190 )?;
191 s.end()
192 }
193 EnumVariant::Struct(_idx, name, fields) => {
194 let mut s = ser.serialize_map(Some(1))?;
195 s.serialize_key(name)?;
196 s.serialize_value(&fields.iter().fold(
197 BTreeMap::new(),
198 |mut m, (name, ty)| {
199 m.insert(*name, self.new_value(&mut data, *ty));
200 m
201 },
202 ))?;
203 s.end()
204 }
205 }
206 }
207 }
208 }
209}
210
211#[inline]
212fn compact_len(data: &[u8]) -> usize {
213 match data[0] % 0b100 {
214 0 => 1,
215 1 => 2,
216 2 => 4,
217 _ => todo!(),
218 }
219}
220
221fn sequence_len(data: &[u8]) -> (usize, usize) {
222 let len = compact_len(data);
226 (
227 match len {
228 1 => (data[0] >> 2).into(),
229 2 => u16::from_le_bytes([(data[0] >> 2), data[1]]).into(),
230 4 => u32::from_le_bytes([(data[0] >> 2), data[1], data[2], data[3]])
231 .try_into()
232 .unwrap(),
233
234 _ => todo!(),
235 },
236 len,
237 )
238}
239
240impl<'reg> AsRef<[u8]> for Value<'reg> {
241 fn as_ref(&self) -> &[u8] {
242 self.data.as_ref()
243 }
244}
245
246#[cfg(feature = "codec")]
247impl<'reg> codec::Encode for Value<'reg> {
248 fn size_hint(&self) -> usize {
249 self.data.len()
250 }
251 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
252 f(self.data.as_ref())
253 }
254}
255
256impl<'reg> core::fmt::Debug for Value<'reg> {
257 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
258 write!(
259 f,
260 "Value {{ data: {:?}, type({}): {:?} }}",
261 self.data,
262 self.ty_id,
263 self.registry.resolve(self.ty_id).unwrap().type_def()
264 )
265 }
266}
267
268#[cfg(feature = "json")]
269impl<'reg> core::fmt::Display for Value<'reg> {
270 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
271 write!(
272 f,
273 "{}",
274 serde_json::to_string(self).map_err(|_| fmt::Error)?
275 )
276 }
277}
278
279#[cfg(feature = "json")]
280impl<'reg> Into<crate::JsonValue> for Value<'reg> {
281 fn into(self) -> crate::JsonValue {
282 serde_json::value::to_value(self).unwrap()
283 }
284}
285
286#[cfg(test)]
287mod tests {
288 use alloc::collections::BTreeMap;
289
290 use super::*;
291 use anyhow::Error;
292 use codec::Encode;
293 use scale_info::{
294 meta_type,
295 prelude::{string::String, vec::Vec},
296 Registry, TypeInfo,
297 };
298 use serde_json::to_value;
299
300 fn register<T>(_ty: &T) -> (u32, PortableRegistry)
301 where
302 T: TypeInfo + 'static,
303 {
304 let mut reg = Registry::new();
305 let sym = reg.register_type(&meta_type::<T>());
306 (sym.id(), reg.into())
307 }
308
309 #[cfg(feature = "json")]
310 #[test]
311 fn display_as_json() {
312 #[derive(Encode, TypeInfo)]
313 struct Foo {
314 bar: String,
315 }
316 let in_value = Foo { bar: "BAZ".into() };
317
318 let data = in_value.encode();
319 let (id, reg) = register(&in_value);
320 let out_value = Value::new(data, id, ®).to_string();
321
322 assert_eq!("{\"bar\":\"BAZ\"}", out_value);
323 }
324
325 #[cfg(feature = "codec")]
326 #[test]
327 fn encodable() {
328 let input = u8::MAX;
329 let (ty, reg) = register(&input);
330 let value = Value::new(b"1234".as_ref(), ty, ®);
331
332 let expected: &[u8] = value.as_ref();
333 assert_eq!(value.encode(), expected);
334 }
335
336 #[test]
337 fn serialize_u8() -> Result<(), Error> {
338 let in_value = u8::MAX;
339 let data = in_value.encode();
340 let (id, reg) = register(&in_value);
341
342 let out_value = Value::new(data, id, ®);
343
344 assert_eq!(to_value(out_value)?, to_value(in_value)?);
345 Ok(())
346 }
347
348 #[test]
349 fn serialize_u16() -> Result<(), Error> {
350 let in_value = u16::MAX;
351 let data = in_value.encode();
352 let (id, reg) = register(&in_value);
353
354 let out_value = Value::new(data, id, ®);
355
356 assert_eq!(to_value(out_value)?, to_value(in_value)?);
357 Ok(())
358 }
359
360 #[test]
361 fn serialize_u32() -> Result<(), Error> {
362 let in_value = u32::MAX;
363 let data = in_value.encode();
364 let (id, reg) = register(&in_value);
365
366 let out_value = Value::new(data, id, ®);
367
368 assert_eq!(to_value(out_value)?, to_value(in_value)?);
369 Ok(())
370 }
371
372 #[test]
373 fn serialize_u64() -> Result<(), Error> {
374 let in_value = u64::MAX;
375 let data = in_value.encode();
376 let (id, reg) = register(&in_value);
377
378 let out_value = Value::new(data, id, ®);
379
380 assert_eq!(to_value(out_value)?, to_value(in_value)?);
381 Ok(())
382 }
383
384 #[test]
385 fn serialize_i16() -> Result<(), Error> {
386 let in_value = i16::MAX;
387 let data = in_value.encode();
388 let (id, reg) = register(&in_value);
389
390 let out_value = Value::new(data, id, ®);
391
392 assert_eq!(to_value(out_value)?, to_value(in_value)?);
393 Ok(())
394 }
395
396 #[test]
397 fn serialize_i32() -> Result<(), Error> {
398 let in_value = i32::MAX;
399 let data = in_value.encode();
400 let (id, reg) = register(&in_value);
401
402 let out_value = Value::new(data, id, ®);
403
404 assert_eq!(to_value(out_value)?, to_value(in_value)?);
405 Ok(())
406 }
407
408 #[test]
409 fn serialize_i64() -> Result<(), Error> {
410 let in_value = i64::MAX;
411 let data = in_value.encode();
412 let (id, reg) = register(&in_value);
413
414 let out_value = Value::new(data, id, ®);
415
416 assert_eq!(to_value(out_value)?, to_value(in_value)?);
417 Ok(())
418 }
419
420 #[test]
421 fn serialize_bool() -> Result<(), Error> {
422 let in_value = true;
423 let data = in_value.encode();
424 let (id, reg) = register(&in_value);
425
426 let out_value = Value::new(data, id, ®);
427
428 assert_eq!(to_value(out_value)?, to_value(in_value)?);
429 Ok(())
430 }
431
432 #[test]
444 fn serialize_u8array() -> Result<(), Error> {
445 let in_value: Vec<u8> = [2u8, u8::MAX].into();
446 let data = in_value.encode();
447 let (id, reg) = register(&in_value);
448
449 let out_value = Value::new(data, id, ®);
450
451 assert_eq!(to_value(out_value)?, to_value(in_value)?);
452 Ok(())
453 }
454
455 #[test]
456 fn serialize_u16array() -> Result<(), Error> {
457 let in_value: Vec<u16> = [2u16, u16::MAX].into();
458 let data = in_value.encode();
459 let (id, reg) = register(&in_value);
460
461 let out_value = Value::new(data, id, ®);
462
463 assert_eq!(to_value(out_value)?, to_value(in_value)?);
464 Ok(())
465 }
466
467 #[test]
468 fn serialize_u32array() -> Result<(), Error> {
469 let in_value: Vec<u32> = [2u32, u32::MAX].into();
470 let data = in_value.encode();
471 let (id, reg) = register(&in_value);
472
473 let out_value = Value::new(data, id, ®);
474
475 assert_eq!(to_value(out_value)?, to_value(in_value)?);
476 Ok(())
477 }
478
479 #[test]
480 fn serialize_tuple() -> Result<(), Error> {
481 let in_value: (i64, Vec<String>, bool) = (
482 i64::MIN,
483 vec!["hello".into(), "big".into(), "world".into()],
484 true,
485 );
486 let data = in_value.encode();
487 let (id, reg) = register(&in_value);
488
489 let out_value = Value::new(data, id, ®);
490
491 assert_eq!(to_value(out_value)?, to_value(in_value)?);
492 Ok(())
493 }
494
495 #[test]
496 fn serialize_simple_u32struct() -> Result<(), Error> {
497 #[derive(Encode, Serialize, TypeInfo)]
498 struct Foo {
499 bar: u32,
500 baz: u32,
501 }
502 let in_value = Foo {
503 bar: 123,
504 baz: u32::MAX,
505 };
506 let data = in_value.encode();
507 let (id, reg) = register(&in_value);
508
509 let out_value = Value::new(data, id, ®);
510
511 assert_eq!(to_value(out_value)?, to_value(in_value)?);
512 Ok(())
513 }
514
515 #[test]
516 fn serialize_simple_u8struct() -> Result<(), Error> {
517 #[derive(Encode, Serialize, TypeInfo)]
518 struct Foo {
519 bar: u8,
520 baz: u8,
521 }
522 let in_value = Foo {
523 bar: 123,
524 baz: u8::MAX,
525 };
526 let data = in_value.encode();
527 let (id, reg) = register(&in_value);
528
529 let out_value = Value::new(data, id, ®);
530
531 assert_eq!(to_value(out_value)?, to_value(in_value)?);
532 Ok(())
533 }
534
535 #[test]
536 fn serialize_simple_u64struct() -> Result<(), Error> {
537 #[derive(Encode, Serialize, TypeInfo)]
538 struct Foo {
539 bar: u64,
540 baz: u64,
541 }
542 let in_value = Foo {
543 bar: 123,
544 baz: u64::MAX,
545 };
546 let data = in_value.encode();
547 let (id, reg) = register(&in_value);
548
549 let out_value = Value::new(data, id, ®);
550
551 assert_eq!(to_value(out_value)?, to_value(in_value)?);
552 Ok(())
553 }
554
555 #[test]
556 fn serialize_map() -> Result<(), Error> {
557 let in_value = {
558 let mut m = BTreeMap::<String, i32>::new();
559 m.insert("foo".into(), i32::MAX);
560 m.insert("bar".into(), i32::MIN);
561 m
562 };
563
564 let data = in_value.encode();
565 let (id, reg) = register(&in_value);
566
567 let out_value = Value::new(data, id, ®);
568
569 assert_eq!(to_value(out_value)?, to_value(in_value)?);
570 Ok(())
571 }
572
573 #[test]
574 fn serialize_complex_struct_with_enum() -> Result<(), Error> {
575 #[derive(Encode, Serialize, TypeInfo)]
576 enum Bar {
577 This,
578 That(i16),
579 }
580 #[derive(Encode, Serialize, TypeInfo)]
581 struct Baz(String);
582 #[derive(Encode, Serialize, TypeInfo)]
583 struct Foo {
584 bar: Vec<Bar>,
585 baz: Option<Baz>,
586 lol: &'static [u8],
587 }
588 let in_value = Foo {
589 bar: [Bar::That(i16::MAX), Bar::This].into(),
590 baz: Some(Baz("aliquam malesuada bibendum arcu vitae".into())),
591 lol: b"\0xFFsome stuff\0x00",
592 };
593 let data = in_value.encode();
594 let (id, reg) = register(&in_value);
595
596 let out_value = Value::new(data, id, ®);
597
598 assert_eq!(to_value(out_value)?, to_value(in_value)?);
599 Ok(())
600 }
601
602 #[test]
603 fn serialize_tuple_struct() -> Result<(), Error> {
604 #[derive(Encode, Serialize, TypeInfo)]
605 struct Foo<'a>([u8; 4], (bool, Option<()>), Baz<'a>, Baz<'a>);
606
607 #[derive(Encode, Serialize, TypeInfo)]
608 struct Bar;
609
610 #[derive(Encode, Serialize, TypeInfo)]
611 enum Baz<'a> {
612 A(Bar),
613 B { bb: &'a str },
614 }
615
616 let in_value = Foo(
617 [1, 2, 3, 4],
618 (false, None),
619 Baz::A(Bar),
620 Baz::B { bb: "lol" },
621 );
622 let data = in_value.encode();
623 let (id, reg) = register(&in_value);
624
625 let out_value = Value::new(data, id, ®);
626
627 assert_eq!(to_value(out_value)?, to_value(in_value)?);
628 Ok(())
629 }
630}