use super::bitvec_helpers;
use crate::prelude::*;
use crate::{Composite, Primitive, Value, ValueDef, Variant};
use serde::{
ser::{SerializeMap, SerializeSeq},
Serialize, Serializer,
};
impl<T> Serialize for Value<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.value.serialize(serializer)
}
}
impl<T> Serialize for ValueDef<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
ValueDef::Composite(val) => val.serialize(serializer),
ValueDef::Variant(val) => val.serialize(serializer),
ValueDef::Primitive(val) => val.serialize(serializer),
ValueDef::BitSequence(val) => bitvec_helpers::serialize_bitvec(val, serializer),
}
}
}
impl<T> Serialize for Composite<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Composite::Named(vals) => {
let mut map = serializer.serialize_map(Some(vals.len()))?;
for (key, val) in vals {
map.serialize_entry(key, val)?;
}
map.end()
}
Composite::Unnamed(vals) => {
let mut seq = serializer.serialize_seq(Some(vals.len()))?;
for val in vals {
seq.serialize_element(val)?;
}
seq.end()
}
}
}
}
macro_rules! serialize_as_first_ok_type {
($serializer:ident $val:ident; $first:ident $($rest:ident)*) => {{
let n: Result<$first,_> = $val.try_into();
match n {
Ok(n) => n.serialize($serializer),
Err(_) => serialize_as_first_ok_type!($serializer $val; $($rest)*)
}
}};
($serializer:ident $val:ident;) => {{
$val.serialize($serializer)
}};
}
impl Serialize for Primitive {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Primitive::Bool(v) => v.serialize(serializer),
Primitive::Char(v) => v.serialize(serializer),
Primitive::String(v) => v.serialize(serializer),
Primitive::U128(v) => {
let v = *v;
serialize_as_first_ok_type!(serializer v; u8 u16 u32 u64 u128)
}
Primitive::U256(v) => v.serialize(serializer),
Primitive::I128(v) => {
let v = *v;
serialize_as_first_ok_type!(serializer v; i8 i16 i32 i64 i128)
}
Primitive::I256(v) => v.serialize(serializer),
}
}
}
impl<T> Serialize for Variant<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(Some(2))?;
map.serialize_entry("name", &self.name)?;
map.serialize_entry("values", &self.values)?;
map.end()
}
}
#[cfg(test)]
mod test {
use crate::value;
use super::*;
use serde_json::json;
fn assert_value(value: Value<()>, expected: serde_json::Value) {
let val = serde_json::to_value(value).expect("can serialize to serde_json::Value");
assert_eq!(val, expected);
}
#[test]
fn serialize_primitives() {
assert_value(Value::u128(1), json!(1));
assert_value(Value::bool(true), json!(true));
assert_value(Value::bool(false), json!(false));
}
#[test]
fn serialize_composites() {
assert_value(
value!({
a: true,
b: "hello",
c: 'c'
}),
json!({
"a": true,
"b": "hello",
"c": 'c'
}),
);
assert_value(value!((true, "hello", 'c')), json!([true, "hello", 'c']))
}
#[test]
fn serialize_variants() {
assert_value(
value!(Foo { a: true, b: "hello", c: 'c' }),
json!({
"name": "Foo",
"values": {
"a": true,
"b": "hello",
"c": 'c'
}
}),
);
assert_value(
value!(Bar(true, "hello", 'c')),
json!({
"name": "Bar",
"values": [
true,
"hello",
'c'
]
}),
)
}
#[test]
fn serialize_bitsequences() {
use scale_bits::bits;
assert_value(
Value::bit_sequence(bits![]),
json!({
"__bitvec__values__": []
}),
);
assert_value(
Value::bit_sequence(bits![0, 1, 1, 0, 1]),
json!({
"__bitvec__values__": [false, true, true, false, true]
}),
);
}
}