sp_ipld/codec.rs
1use bytecursor::ByteCursor;
2use sp_cid::Cid;
3
4use alloc::{
5 string::String,
6 vec::Vec
7};
8use core::{
9 convert::TryFrom,
10 ops::Deref,
11};
12
13pub struct UnsupportedCodec(pub u64);
14
15pub enum Error {
16 UnsupportedCodec(u64),
17}
18
19pub trait Codec:
20 Copy
21 + Unpin
22 + Send
23 + Sync
24 + 'static
25 + Sized
26 + TryFrom<u64, Error = UnsupportedCodec>
27 + Into<u64> {
28 /// # Errors
29 ///
30 /// Will return `Err` if there was a problem encoding the object into a
31 /// `ByteCursor`
32 fn encode<T: Encode<Self> + ?Sized>(
33 &self,
34 obj: &T,
35 ) -> Result<ByteCursor, String> {
36 let mut buf = ByteCursor::new(Vec::with_capacity(u16::MAX as usize));
37 obj.encode(*self, &mut buf)?;
38 Ok(buf)
39 }
40
41 /// # Errors
42 ///
43 /// Will return `Err` if there was a problem decoding the `ByteCursor` into an
44 /// object
45 fn decode<T: Decode<Self>>(
46 &self,
47 mut bytes: ByteCursor,
48 ) -> Result<T, String> {
49 T::decode(*self, &mut bytes)
50 }
51
52 /// Extends `set` with any cids the type encoded in the bytecursor
53 /// refers to.
54 ///
55 /// # Errors
56 ///
57 /// Returns `Err` if there were any errors decoding the bytecursor.
58 fn references<T: References<Self>, E: Extend<Cid>>(
59 &self,
60 mut bytes: ByteCursor,
61 set: &mut E,
62 ) -> Result<(), String> {
63 T::references(*self, &mut bytes, set)
64 }
65}
66
67/// A trait to represent the ability to encode with
68/// the codec `C` for the type.
69pub trait Encode<C: Codec> {
70 /// Encodes `Self` using codec `C` into the mutable bytecursor
71 /// `w`. Returns `Ok` if the encoding process succeeded.
72 ///
73 /// # Errors
74 ///
75 /// Will return `Err` if there was a problem during encoding
76 fn encode(&self, c: C, w: &mut ByteCursor) -> Result<(), String>;
77}
78
79impl<C: Codec, T: Encode<C>> Encode<C> for &T {
80 fn encode(&self, c: C, w: &mut ByteCursor) -> Result<(), String> {
81 self.deref().encode(c, w)
82 }
83}
84
85/// A trait representing the ability to decode with
86/// the codec `C` for the type.
87pub trait Decode<C: Codec>: Sized {
88 /// Decodes the bytes in `r` using the codec `C` into
89 /// `Self`. Returns `ok` if the bytes represented a valid
90 /// value of the type.
91 ///
92 /// # Errors
93 ///
94 /// Will return `Err` if there was a problem during decoding
95 fn decode(c: C, r: &mut ByteCursor) -> Result<Self, String>;
96}
97
98/// A trait representing the ability to count cid references in the
99/// encoding of the type with the codec `C`
100pub trait References<C: Codec>: Sized {
101 /// Extends `set` with any Cid references found in the encoding
102 /// of the type in `r` with the codec `C`
103 ///
104 /// # Errors
105 ///
106 /// Will return `Err` if `r` did not contain a valid encoding of the
107 /// type with codec `C`.
108 fn references<E: Extend<Cid>>(
109 c: C,
110 r: &mut ByteCursor,
111 set: &mut E,
112 ) -> Result<(), String>;
113}
114
115/// A trait for codecs representing the ability to skip values.
116pub trait SkipOne: Codec {
117 /// Skips a single value of the encoded type using the given codec in `r`.
118 ///
119 /// # Errors
120 ///
121 /// Will return `Err` if there was a problem during skipping
122 fn skip(&self, r: &mut ByteCursor) -> Result<(), String>;
123}