use crate::{AbiType, AbiValue};
use iter_extended::vecmap;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Serialize, Deserialize)]
struct StructField {
name: String,
#[serde(rename = "type")]
typ: AbiType,
}
pub(crate) fn serialize_struct_fields<S>(
fields: &[(String, AbiType)],
s: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let fields_vector =
vecmap(fields, |(name, typ)| StructField { name: name.to_owned(), typ: typ.to_owned() });
fields_vector.serialize(s)
}
pub(crate) fn deserialize_struct_fields<'de, D>(
deserializer: D,
) -> Result<Vec<(String, AbiType)>, D::Error>
where
D: Deserializer<'de>,
{
let fields_vector = Vec::<StructField>::deserialize(deserializer)?;
Ok(vecmap(fields_vector, |StructField { name, typ }| (name, typ)))
}
#[derive(Serialize, Deserialize)]
struct StructFieldValue {
name: String,
value: AbiValue,
}
pub(crate) fn serialize_struct_field_values<S>(
fields: &[(String, AbiValue)],
s: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let fields_vector = vecmap(fields, |(name, value)| StructFieldValue {
name: name.to_owned(),
value: value.to_owned(),
});
fields_vector.serialize(s)
}
pub(crate) fn deserialize_struct_field_values<'de, D>(
deserializer: D,
) -> Result<Vec<(String, AbiValue)>, D::Error>
where
D: Deserializer<'de>,
{
let fields_vector = Vec::<StructFieldValue>::deserialize(deserializer)?;
Ok(vecmap(fields_vector, |StructFieldValue { name, value }| (name, value)))
}
#[cfg(test)]
mod tests {
use crate::{AbiParameter, AbiType, AbiVisibility, Sign};
#[test]
fn abi_parameter_serialization() {
let serialized_field = "{
\"name\": \"thing1\",
\"visibility\": \"public\",
\"type\": {
\"kind\": \"field\"
}
}";
let expected_field = AbiParameter {
name: "thing1".to_string(),
typ: AbiType::Field,
visibility: AbiVisibility::Public,
};
let deserialized_field: AbiParameter = serde_json::from_str(serialized_field).unwrap();
assert_eq!(deserialized_field, expected_field);
let serialized_array = "{
\"name\": \"thing2\",
\"visibility\": \"private\",
\"type\": {
\"kind\": \"array\",
\"length\": 2,
\"type\": {
\"kind\": \"integer\",
\"width\": 3,
\"sign\": \"unsigned\"
}
}
}";
let expected_array = AbiParameter {
name: "thing2".to_string(),
typ: AbiType::Array {
length: 2,
typ: Box::new(AbiType::Integer { sign: Sign::Unsigned, width: 3 }),
},
visibility: AbiVisibility::Private,
};
let deserialized_array: AbiParameter = serde_json::from_str(serialized_array).unwrap();
assert_eq!(deserialized_array, expected_array);
let serialized_struct = "{
\"name\":\"thing3\",
\"type\": {
\"kind\":\"struct\",
\"path\": \"MyStruct\",
\"fields\": [
{
\"name\": \"field1\",
\"type\": {
\"kind\": \"integer\",
\"sign\": \"unsigned\",
\"width\": 3
}
},
{
\"name\":\"field2\",
\"type\": {
\"kind\":\"array\",
\"length\": 2,
\"type\": {
\"kind\":\"field\"
}
}
}
]
},
\"visibility\":\"private\"
}";
let expected_struct = AbiParameter {
name: "thing3".to_string(),
typ: AbiType::Struct {
path: "MyStruct".to_string(),
fields: vec![
("field1".to_string(), AbiType::Integer { sign: Sign::Unsigned, width: 3 }),
(
"field2".to_string(),
AbiType::Array { length: 2, typ: Box::new(AbiType::Field) },
),
],
},
visibility: AbiVisibility::Private,
};
let deserialized_struct: AbiParameter = serde_json::from_str(serialized_struct).unwrap();
assert_eq!(deserialized_struct, expected_struct);
}
}