platform_value/converter/
ciborium.rs1use crate::value_map::ValueMap;
2use crate::{Error, Value, ValueMapHelper};
3use ciborium::value::Integer;
4use ciborium::Value as CborValue;
5
6impl Value {
7 pub fn convert_from_cbor_map<I, R>(map: I) -> Result<R, Error>
8 where
9 I: IntoIterator<Item = (String, CborValue)>,
10 R: FromIterator<(String, Value)>,
11 {
12 map.into_iter()
13 .map(|(key, cbor_value)| Ok((key, cbor_value.try_into()?)))
14 .collect()
15 }
16
17 pub fn convert_to_cbor_map<I, R>(map: I) -> Result<R, Error>
18 where
19 I: IntoIterator<Item = (String, Value)>,
20 R: FromIterator<(String, CborValue)>,
21 {
22 map.into_iter()
23 .map(|(key, value)| Ok((key, value.try_into()?)))
24 .collect()
25 }
26
27 pub fn to_cbor_buffer(&self) -> Result<Vec<u8>, Error> {
28 let mut buffer: Vec<u8> = Vec::new();
29 ciborium::ser::into_writer(self, &mut buffer)
30 .map_err(|e| Error::CborSerializationError(e.to_string()))?;
31
32 Ok(buffer)
33 }
34}
35
36impl TryFrom<CborValue> for Value {
37 type Error = Error;
38
39 fn try_from(value: CborValue) -> Result<Self, Error> {
40 Ok(match value {
41 CborValue::Integer(integer) => Self::I128(integer.into()),
42 CborValue::Bytes(bytes) => Self::Bytes(bytes),
43 CborValue::Float(float) => Self::Float(float),
44 CborValue::Text(string) => Self::Text(string),
45 CborValue::Bool(value) => Self::Bool(value),
46 CborValue::Null => Self::Null,
47 CborValue::Tag(_, _) => {
48 return Err(Error::Unsupported(
49 "conversion from cbor tags are currently not supported".to_string(),
50 ))
51 }
52 CborValue::Array(array) => {
53 let len = array.len();
54 if len > 10
55 && array.iter().all(|v| {
56 let Some(int) = v.as_integer() else {
57 return false;
58 };
59 int.le(&Integer::from(u8::MAX)) && int.ge(&Integer::from(0))
60 })
61 {
62 Self::Bytes(
64 array
65 .into_iter()
66 .map(|v| v.into_integer().unwrap().try_into().unwrap())
67 .collect(),
68 )
69 } else {
70 Self::Array(
71 array
72 .into_iter()
73 .map(|v| v.try_into())
74 .collect::<Result<Vec<Value>, Error>>()?,
75 )
76 }
77 }
78 CborValue::Map(map) => Self::Map(
79 map.into_iter()
80 .map(|(k, v)| Ok((k.try_into()?, v.try_into()?)))
81 .collect::<Result<ValueMap, Error>>()?,
82 ),
83 _ => panic!("unsupported"),
84 })
85 }
86}
87
88impl TryInto<CborValue> for Value {
89 type Error = Error;
90
91 fn try_into(self) -> Result<CborValue, Self::Error> {
92 Ok(match self {
93 Value::U128(i) => CborValue::Integer((i as u64).into()),
94 Value::I128(i) => CborValue::Integer((i as i64).into()),
95 Value::U64(i) => CborValue::Integer(i.into()),
96 Value::I64(i) => CborValue::Integer(i.into()),
97 Value::U32(i) => CborValue::Integer(i.into()),
98 Value::I32(i) => CborValue::Integer(i.into()),
99 Value::U16(i) => CborValue::Integer(i.into()),
100 Value::I16(i) => CborValue::Integer(i.into()),
101 Value::U8(i) => CborValue::Integer(i.into()),
102 Value::I8(i) => CborValue::Integer(i.into()),
103 Value::Bytes(bytes) => CborValue::Bytes(bytes),
104 Value::Bytes20(bytes) => CborValue::Bytes(bytes.to_vec()),
105 Value::Bytes32(bytes) => CborValue::Bytes(bytes.to_vec()),
106 Value::Bytes36(bytes) => CborValue::Bytes(bytes.to_vec()),
107 Value::Float(float) => CborValue::Float(float),
108 Value::Text(string) => CborValue::Text(string),
109 Value::Bool(value) => CborValue::Bool(value),
110 Value::Null => CborValue::Null,
111 Value::Array(array) => CborValue::Array(
112 array
113 .into_iter()
114 .map(|value| value.try_into())
115 .collect::<Result<Vec<CborValue>, Error>>()?,
116 ),
117 Value::Map(mut map) => {
118 map.sort_by_keys();
119 CborValue::Map(
120 map.into_iter()
121 .map(|(k, v)| Ok((k.try_into()?, v.try_into()?)))
122 .collect::<Result<Vec<(CborValue, CborValue)>, Error>>()?,
123 )
124 }
125 Value::Identifier(bytes) => CborValue::Bytes(bytes.to_vec()),
126 Value::EnumU8(_) => {
127 return Err(Error::Unsupported(
128 "No support for conversion of EnumU8 to JSONValue".to_string(),
129 ))
130 }
131 Value::EnumString(_) => {
132 return Err(Error::Unsupported(
133 "No support for conversion of EnumString to JSONValue".to_string(),
134 ))
135 }
136 })
137 }
138}
139
140impl TryInto<Box<CborValue>> for Box<Value> {
141 type Error = Error;
142 fn try_into(self) -> Result<Box<CborValue>, Self::Error> {
143 (*self).try_into().map(Box::new)
144 }
145}