ergotree_ir/serialization/
serializable.rs1use crate::chain::ergo_box::RegisterValueError;
3use crate::ergo_tree::ErgoTreeHeaderError;
4use crate::mir::val_def::ValId;
5use crate::mir::{constant::TryExtractFromError, expr::InvalidArgumentError};
6use crate::types::type_unify::TypeUnificationError;
7
8use super::{
9 constant_store::ConstantStore,
10 sigma_byte_reader::{SigmaByteRead, SigmaByteReader},
11 sigma_byte_writer::{SigmaByteWrite, SigmaByteWriter},
12};
13use crate::types::smethod::MethodId;
14use bounded_vec::BoundedVec;
15use bounded_vec::BoundedVecOutOfBounds;
16use io::Cursor;
17use sigma_ser::{vlq_encode, ScorexParsingError, ScorexSerializationError};
18use std::convert::TryInto;
19use std::io;
20use thiserror::Error;
21
22#[derive(Error, Eq, PartialEq, Debug, Clone)]
24pub enum SigmaSerializationError {
25 #[error("IO error: {0}")]
27 Io(String),
28 #[error("serialization not yet implemented: {0}")]
30 NotImplementedYet(&'static str),
31 #[error("Unexpected value: {0:?}")]
33 UnexpectedValue(#[from] TryExtractFromError),
34 #[error("serialization not supported: {0}")]
36 NotSupported(String),
37 #[error("Scorex serialization error: {0}")]
39 ScorexSerializationError(#[from] ScorexSerializationError),
40}
41
42impl From<io::Error> for SigmaSerializationError {
43 fn from(error: io::Error) -> Self {
44 SigmaSerializationError::Io(error.to_string())
45 }
46}
47
48#[derive(Error, Eq, PartialEq, Debug, Clone)]
50pub enum SigmaParsingError {
51 #[error("invalid op code: {0}")]
53 InvalidOpCode(u8),
54 #[error("not implemented op error: {0}")]
56 NotImplementedOpCode(String),
57 #[error("type parsing error, invalid type code: {0}({0:#04X})")]
59 InvalidTypeCode(u8),
60 #[error("vlq encode error: {0}")]
62 VlqEncode(#[from] vlq_encode::VlqEncodingError),
63 #[error("IO error: {0}")]
65 Io(String),
66 #[error("misc error: {0}")]
68 Misc(String),
69 #[error("parsing not yet implemented: {0}")]
71 NotImplementedYet(String),
72 #[error("Constant with index {0} not found in constant store")]
74 ConstantForPlaceholderNotFound(u32),
75 #[error("Value out of bounds: {0}")]
77 ValueOutOfBounds(String),
78 #[error("Tuple items out of bounds: {0}")]
80 TupleItemsOutOfBounds(usize),
81 #[error("ValDef type for an index {0:?} not found in ValDefTypeStore store")]
83 ValDefIdNotFound(ValId),
84 #[error("Invalid argument: {0:?}")]
86 InvalidArgument(#[from] InvalidArgumentError),
87 #[error("No method id {0:?} found in type companion with type id {1:?} ")]
89 UnknownMethodId(MethodId, u8),
90 #[error("parsing not supported: {0}")]
92 NotSupported(&'static str),
93 #[error("serialization error: {0}")]
95 SerializationError(#[from] SigmaSerializationError),
96 #[error("Invalid item quantity for BoundedVec: {0}")]
98 BoundedVecOutOfBounds(#[from] BoundedVecOutOfBounds),
99 #[error("Scorex parsing error: {0}")]
101 ScorexParsingError(#[from] ScorexParsingError),
102 #[error("ErgoTreeHeaderError: {0}")]
104 ErgoTreeHeaderError(#[from] ErgoTreeHeaderError),
105 #[error("Invalid register value: {0}")]
107 InvalidRegisterValue(#[from] RegisterValueError),
108}
109
110impl From<io::Error> for SigmaParsingError {
111 fn from(error: io::Error) -> Self {
112 SigmaParsingError::Io(error.to_string())
113 }
114}
115
116impl From<&io::Error> for SigmaParsingError {
117 fn from(error: &io::Error) -> Self {
118 SigmaParsingError::Io(error.to_string())
119 }
120}
121
122impl From<TypeUnificationError> for SigmaParsingError {
123 fn from(e: TypeUnificationError) -> Self {
124 SigmaParsingError::Misc(format!("{:?}", e))
125 }
126}
127
128pub type SigmaSerializeResult = Result<(), SigmaSerializationError>;
130
131pub trait SigmaSerializable: Sized {
133 fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult;
138
139 fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> Result<Self, SigmaParsingError>;
143
144 fn sigma_serialize_bytes(&self) -> Result<Vec<u8>, SigmaSerializationError> {
146 let mut data = Vec::new();
147 let mut w = SigmaByteWriter::new(&mut data, None);
148 self.sigma_serialize(&mut w)?;
149 Ok(data)
150 }
151
152 fn sigma_parse_bytes(bytes: &[u8]) -> Result<Self, SigmaParsingError> {
154 let cursor = Cursor::new(bytes);
155 let mut sr = SigmaByteReader::new(cursor, ConstantStore::empty());
156 Self::sigma_parse(&mut sr)
157 }
158}
159
160impl<T: SigmaSerializable> SigmaSerializable for Vec<T> {
161 fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult {
162 w.put_u32(self.len() as u32)?;
163 self.iter().try_for_each(|i| i.sigma_serialize(w))
164 }
165
166 fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> Result<Self, SigmaParsingError> {
167 let items_count = r.get_u32()?;
168 let mut items = Vec::with_capacity(items_count as usize);
169 for _ in 0..items_count {
170 items.push(T::sigma_parse(r)?);
171 }
172 Ok(items)
173 }
174}
175
176impl<T: SigmaSerializable, const L: usize, const U: usize> SigmaSerializable
177 for BoundedVec<T, L, U>
178{
179 fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult {
180 self.as_vec().sigma_serialize(w)
181 }
182
183 fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> Result<Self, SigmaParsingError> {
184 Ok(Vec::<T>::sigma_parse(r)?.try_into()?)
185 }
186}
187
188impl SigmaSerializable for u32 {
190 fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult {
191 w.put_u32(*self)?;
192 Ok(())
193 }
194 fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> Result<Self, SigmaParsingError> {
195 let v = r.get_u32()?;
196 Ok(v)
197 }
198}
199
200impl<T: SigmaSerializable> SigmaSerializable for Option<Box<T>> {
201 fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult {
202 match self {
203 Some(v) => {
204 w.put_u8(1)?;
205 v.sigma_serialize(w)
206 }
207 None => Ok(w.put_u8(0)?),
208 }
209 }
210
211 fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> Result<Self, SigmaParsingError> {
212 let tag = r.get_u8()?;
213 Ok(if tag != 0 {
214 Some(T::sigma_parse(r)?.into())
215 } else {
216 None
217 })
218 }
219}
220
221#[allow(clippy::expect_used)]
223pub fn sigma_serialize_roundtrip<T: SigmaSerializable>(v: &T) -> T {
224 let mut data = Vec::new();
225 let mut w = SigmaByteWriter::new(&mut data, None);
226 v.sigma_serialize(&mut w).expect("serialization failed");
227 let cursor = Cursor::new(&mut data[..]);
228 let mut sr = SigmaByteReader::new(cursor, ConstantStore::empty());
229 T::sigma_parse(&mut sr).expect("parse failed")
230}