1use crate::{
2 codec::Encode,
3 dag_cbor::DagCborCodec,
4 ipld::Ipld,
5};
6
7use alloc::{
8 borrow::ToOwned,
9 boxed::Box,
10 string::String,
11 sync::Arc,
12};
13use bytecursor::ByteCursor;
14use byteorder::{
15 BigEndian,
16 ByteOrder,
17};
18use sp_cid::Cid;
19use alloc::{
20 collections::btree_map::BTreeMap,
21 vec::Vec,
22};
23
24use core::{
25 convert::TryFrom,
26 mem,
27 ops::Deref,
28};
29
30fn write_null(w: &mut ByteCursor) -> Result<(), String> {
35 w.write_all(&[0xf6])?;
36 Ok(())
37}
38
39fn write_u8(w: &mut ByteCursor, major: u8, value: u8) -> Result<(), String> {
44 if value <= 0x17 {
45 let buf = [major << 5 | value];
46 w.write_all(&buf)?;
47 }
48 else {
49 let buf = [major << 5 | 24, value];
50 w.write_all(&buf)?;
51 }
52 Ok(())
53}
54
55fn write_u16(w: &mut ByteCursor, major: u8, value: u16) -> Result<(), String> {
60 if let Ok(small) = u8::try_from(value) {
61 write_u8(w, major, small)?;
62 }
63 else {
64 let mut buf = [major << 5 | 25, 0, 0];
65 BigEndian::write_u16(&mut buf[1..], value);
66 w.write_all(&buf)?;
67 }
68 Ok(())
69}
70
71fn write_u32(w: &mut ByteCursor, major: u8, value: u32) -> Result<(), String> {
76 if let Ok(small) = u16::try_from(value) {
77 write_u16(w, major, small)?;
78 }
79 else {
80 let mut buf = [major << 5 | 26, 0, 0, 0, 0];
81 BigEndian::write_u32(&mut buf[1..], value);
82 w.write_all(&buf)?;
83 }
84 Ok(())
85}
86
87fn write_u64(w: &mut ByteCursor, major: u8, value: u64) -> Result<(), String> {
92 if let Ok(small) = u32::try_from(value) {
93 write_u32(w, major, small)?;
94 }
95 else {
96 let mut buf = [major << 5 | 27, 0, 0, 0, 0, 0, 0, 0, 0];
97 BigEndian::write_u64(&mut buf[1..], value);
98 w.write_all(&buf)?;
99 }
100 Ok(())
101}
102
103fn write_tag(w: &mut ByteCursor, tag: u64) -> Result<(), String> {
108 write_u64(w, 6, tag)
109}
110impl Encode<DagCborCodec> for bool {
111 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
112 let buf = if *self { [0xf5] } else { [0xf4] };
113 w.write_all(&buf)?;
114 Ok(())
115 }
116}
117impl Encode<DagCborCodec> for u8 {
118 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
119 write_u8(w, 0, *self)
120 }
121}
122impl Encode<DagCborCodec> for u16 {
123 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
124 write_u16(w, 0, *self)
125 }
126}
127impl Encode<DagCborCodec> for u32 {
128 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
129 write_u32(w, 0, *self)
130 }
131}
132impl Encode<DagCborCodec> for u64 {
133 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
134 write_u64(w, 0, *self)
135 }
136}
137impl Encode<DagCborCodec> for i8 {
138 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
139 write_u8(w, 1, -(*self + 1) as u8) }
141}
142impl Encode<DagCborCodec> for i16 {
143 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
144 write_u16(w, 1, -(*self + 1) as u16) }
146}
147impl Encode<DagCborCodec> for i32 {
148 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
149 write_u32(w, 1, -(*self + 1) as u32) }
151}
152impl Encode<DagCborCodec> for i64 {
153 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
154 write_u64(w, 1, -(*self + 1) as u64) }
156}
157impl Encode<DagCborCodec> for f32 {
158 #[allow(clippy::float_cmp)]
159 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
160 if self.is_infinite() {
161 if self.is_sign_positive() {
162 w.write_all(&[0xf9, 0x7c, 0x00])?;
163 }
164 else {
165 w.write_all(&[0xf9, 0xfc, 0x00])?;
166 }
167 }
168 else if self.is_nan() {
169 w.write_all(&[0xf9, 0x7e, 0x00])?;
170 }
171 else {
172 let mut buf = [0xfa, 0, 0, 0, 0];
173 BigEndian::write_f32(&mut buf[1..], *self);
174 w.write_all(&buf)?;
175 }
176 Ok(())
177 }
178}
179impl Encode<DagCborCodec> for f64 {
180 #[allow(clippy::float_cmp)]
181 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
182 if !self.is_finite() || Self::from(*self as f32) == *self {
183 let value = *self as f32;
185 value.encode(c, w)?;
186 }
187 else {
188 let mut buf = [0xfb, 0, 0, 0, 0, 0, 0, 0, 0];
190 BigEndian::write_f64(&mut buf[1..], *self);
191 w.write_all(&buf)?;
192 }
193 Ok(())
194 }
195}
196impl Encode<DagCborCodec> for [u8] {
197 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
198 write_u64(w, 2, self.len() as u64)?;
199 w.write_all(self)?;
200 Ok(())
201 }
202}
203impl Encode<DagCborCodec> for Box<[u8]> {
204 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
205 self[..].encode(c, w)
206 }
207}
208impl Encode<DagCborCodec> for str {
209 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
210 write_u64(w, 3, self.len() as u64)?;
211 w.write_all(self.as_bytes())?;
212 Ok(())
213 }
214}
215impl Encode<DagCborCodec> for String {
216 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
217 self.as_str().encode(c, w)
218 }
219}
220impl Encode<DagCborCodec> for i128 {
221 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
222 if *self < 0 {
223 if -(*self + 1) > u64::max_value() as i128 {
224 return Err("Number out of range.".to_owned());
225 }
226 write_u64(w, 1, -(*self + 1) as u64)?;
227 }
228 else {
229 if *self > u64::max_value() as i128 {
230 return Err("Number out of range.".to_owned());
231 }
232 write_u64(w, 0, *self as u64)?;
233 }
234 Ok(())
235 }
236}
237impl Encode<DagCborCodec> for Cid {
238 fn encode(&self, _: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
239 write_tag(w, 42)?;
240 let buf = self.to_bytes();
243 let len = buf.len();
244 write_u64(w, 2, len as u64 + 1)?;
245 w.write_all(&[0])?;
246 w.write_all(&buf[..len])?;
247 Ok(())
248 }
249}
250impl<T: Encode<DagCborCodec>> Encode<DagCborCodec> for Option<T> {
251 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
252 if let Some(value) = self {
253 value.encode(c, w)?;
254 }
255 else {
256 write_null(w)?;
257 }
258 Ok(())
259 }
260}
261impl<T: Encode<DagCborCodec>> Encode<DagCborCodec> for Vec<T> {
262 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
263 write_u64(w, 4, self.len() as u64)?;
264 for value in self {
265 value.encode(c, w)?;
266 }
267 Ok(())
268 }
269}
270impl<K: Encode<DagCborCodec>, T: Encode<DagCborCodec> + 'static>
271 Encode<DagCborCodec> for BTreeMap<K, T>
272{
273 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
274 write_u64(w, 5, self.len() as u64)?;
275 let mut vec: Vec<_> = self.iter().collect();
276 vec.sort_unstable_by(|&(k1, _), &(k2, _)| {
277 let mut bc1 = ByteCursor::new(Vec::new());
278 mem::drop(k1.encode(c, &mut bc1));
279 let mut bc2 = ByteCursor::new(Vec::new());
280 mem::drop(k2.encode(c, &mut bc2));
281 bc1.into_inner().cmp(&bc2.into_inner())
282 });
283 for (k, v) in vec {
284 k.encode(c, w)?;
285 v.encode(c, w)?;
286 }
287 Ok(())
288 }
289}
290impl Encode<DagCborCodec> for Ipld {
291 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
292 match self {
293 Self::Null => write_null(w),
294 Self::Bool(b) => b.encode(c, w),
295 Self::Integer(i) => i.encode(c, w),
296 Self::Float(f) => f.encode(c, w),
297 Self::Bytes(b) => b.as_slice().encode(c, w),
298 Self::String(s) => s.encode(c, w),
299 Self::List(l) => l.encode(c, w),
300 Self::StringMap(m) => m.encode(c, w),
301 Self::Link(cid) => cid.encode(c, w),
302 }
303 }
304}
305impl<T: Encode<DagCborCodec>> Encode<DagCborCodec> for Arc<T> {
306 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
307 self.deref().encode(c, w)
308 }
309}
310impl Encode<DagCborCodec> for () {
311 fn encode(&self, _c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
312 write_u8(w, 4, 0)?;
313 Ok(())
314 }
315}
316impl<A: Encode<DagCborCodec>> Encode<DagCborCodec> for (A,) {
317 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
318 write_u8(w, 4, 1)?;
319 self.0.encode(c, w)?;
320 Ok(())
321 }
322}
323impl<A: Encode<DagCborCodec>, B: Encode<DagCborCodec>> Encode<DagCborCodec>
324 for (A, B)
325{
326 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
327 write_u8(w, 4, 2)?;
328 self.0.encode(c, w)?;
329 self.1.encode(c, w)?;
330 Ok(())
331 }
332}
333impl<A: Encode<DagCborCodec>, B: Encode<DagCborCodec>, C: Encode<DagCborCodec>>
334 Encode<DagCborCodec> for (A, B, C)
335{
336 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
337 write_u8(w, 4, 3)?;
338 self.0.encode(c, w)?;
339 self.1.encode(c, w)?;
340 self.2.encode(c, w)?;
341 Ok(())
342 }
343}
344impl<
345 A: Encode<DagCborCodec>,
346 B: Encode<DagCborCodec>,
347 C: Encode<DagCborCodec>,
348 D: Encode<DagCborCodec>,
349> Encode<DagCborCodec> for (A, B, C, D)
350{
351 fn encode(&self, c: DagCborCodec, w: &mut ByteCursor) -> Result<(), String> {
352 write_u8(w, 4, 4)?;
353 self.0.encode(c, w)?;
354 self.1.encode(c, w)?;
355 self.2.encode(c, w)?;
356 self.3.encode(c, w)?;
357 Ok(())
358 }
359}