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}