• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ergoplatform / sigma-rust / 12688397824

09 Jan 2025 10:48AM UTC coverage: 78.524% (+0.07%) from 78.451%
12688397824

Pull #803

github

web-flow
Merge 7cdf7e630 into 444347ba8
Pull Request #803: Adding context.getvarfrominput and context.getvar

42 of 57 new or added lines in 3 files covered. (73.68%)

8 existing lines in 1 file now uncovered.

11148 of 14197 relevant lines covered (78.52%)

3.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.12
/ergotree-ir/src/serialization/types.rs
1
use super::op_code::OpCode;
2
use super::sigma_byte_writer::SigmaByteWrite;
3
use super::SigmaSerializationError;
4
use crate::serialization::SigmaSerializeResult;
5
use crate::serialization::{
6
    sigma_byte_reader::SigmaByteRead, SigmaParsingError, SigmaSerializable,
7
};
8
use crate::types::stuple;
9
use crate::types::stype::SType;
10
use crate::types::stype_param;
11
use alloc::string::ToString;
12
use alloc::vec::Vec;
13
use core::convert::TryInto;
14
use num_derive::FromPrimitive;
15
use num_traits::FromPrimitive;
16

17
#[allow(non_camel_case_types)]
18
#[allow(clippy::upper_case_acronyms)] // to differentiate from similarly named SType enum variants
19
#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive)]
20
#[repr(u8)]
21
pub enum TypeCode {
22
    SBOOLEAN = 1,
23
    SBYTE = 2,
24
    SSHORT = 3,
25
    SINT = 4,
26
    SLONG = 5,
27
    SBIGINT = 6,
28
    SGROUP_ELEMENT = 7,
29
    SSIGMAPROP = 8,
30

31
    COLL = (TypeCode::MAX_PRIM_TYPECODE + 1) * TypeCode::COLLECTION_CONSTR_ID, // 12 * 1
32
    COLL_BOOL = TypeCode::COLL as u8 + TypeCode::SBOOLEAN as u8,               // 13
33
    COLL_BYTE = TypeCode::COLL as u8 + TypeCode::SBYTE as u8,                  // 14
34
    COLL_SHORT = TypeCode::COLL as u8 + TypeCode::SSHORT as u8,                // 15
35
    COLL_INT = TypeCode::COLL as u8 + TypeCode::SINT as u8,                    // 16
36
    COLL_LONG = TypeCode::COLL as u8 + TypeCode::SLONG as u8,                  // 17
37
    COLL_BIGINT = TypeCode::COLL as u8 + TypeCode::SBIGINT as u8,              // 18
38
    COLL_GROUP_ELEMENT = TypeCode::COLL as u8 + TypeCode::SGROUP_ELEMENT as u8, // 19
39
    COLL_SIGMAPROP = TypeCode::COLL as u8 + TypeCode::SSIGMAPROP as u8,        // 20
40

41
    NESTED_COLL_BOOL = TypeCode::NESTED_COLL + TypeCode::SBOOLEAN as u8, // 25
42
    NESTED_COLL_BYTE = TypeCode::NESTED_COLL + TypeCode::SBYTE as u8,    // 26
43
    NESTED_COLL_SHORT = TypeCode::NESTED_COLL + TypeCode::SSHORT as u8,  // 27
44
    NESTED_COLL_INT = TypeCode::NESTED_COLL + TypeCode::SINT as u8,      // 28
45
    NESTED_COLL_LONG = TypeCode::NESTED_COLL + TypeCode::SLONG as u8,    // 29
46
    NESTED_COLL_BIGINT = TypeCode::NESTED_COLL + TypeCode::SBIGINT as u8, // 30
47
    NESTED_COLL_GROUP_ELEMENT = TypeCode::NESTED_COLL + TypeCode::SGROUP_ELEMENT as u8, // 31
48
    NESTED_COLL_SIGMAPROP = TypeCode::NESTED_COLL + TypeCode::SSIGMAPROP as u8, // 32
49

50
    OPTION = (TypeCode::MAX_PRIM_TYPECODE + 1) * TypeCode::OPTION_CONSTR_ID, // 12 * 3 = 36
51
    OPTION_BOOL = TypeCode::OPTION as u8 + TypeCode::SBOOLEAN as u8,         // 37
52
    OPTION_BYTE = TypeCode::OPTION as u8 + TypeCode::SBYTE as u8,            // 38
53
    OPTION_SHORT = TypeCode::OPTION as u8 + TypeCode::SSHORT as u8,          // 39
54
    OPTION_INT = TypeCode::OPTION as u8 + TypeCode::SINT as u8,              // 40
55
    OPTION_LONG = TypeCode::OPTION as u8 + TypeCode::SLONG as u8,            // 41
56
    OPTION_BIGINT = TypeCode::OPTION as u8 + TypeCode::SBIGINT as u8,        // 42
57
    OPTION_GROUP_ELEMENT = TypeCode::OPTION as u8 + TypeCode::SGROUP_ELEMENT as u8, // 43
58
    OPTION_SIGMAPROP = TypeCode::OPTION as u8 + TypeCode::SSIGMAPROP as u8,  // 44
59

60
    OPTION_COLL_BOOL = TypeCode::OPTION_COLLECTION + TypeCode::SBOOLEAN as u8, // 49
61
    OPTION_COLL_BYTE = TypeCode::OPTION_COLLECTION + TypeCode::SBYTE as u8,    // 50
62
    OPTION_COLL_SHORT = TypeCode::OPTION_COLLECTION + TypeCode::SSHORT as u8,  // 51
63
    OPTION_COLL_INT = TypeCode::OPTION_COLLECTION + TypeCode::SINT as u8,      // 52
64
    OPTION_COLL_LONG = TypeCode::OPTION_COLLECTION + TypeCode::SLONG as u8,    // 53
65
    OPTION_COLL_BIGINT = TypeCode::OPTION_COLLECTION + TypeCode::SBIGINT as u8, // 54
66
    OPTION_COLL_GROUP_ELEMENT = TypeCode::OPTION_COLLECTION + TypeCode::SGROUP_ELEMENT as u8, // 55
67
    OPTION_COLL_SIGMAPROP = TypeCode::OPTION_COLLECTION + TypeCode::SSIGMAPROP as u8, // 56
68

69
    TUPLE_PAIR1 = (TypeCode::MAX_PRIM_TYPECODE + 1) * TypeCode::TUPLE_PAIR1_CONSTR_ID, // 12 * 5 = 60
70
    TUPLE_PAIR1_BOOL = TypeCode::TUPLE_PAIR1 as u8 + TypeCode::SBOOLEAN as u8,         // 61
71
    TUPLE_PAIR1_BYTE = TypeCode::TUPLE_PAIR1 as u8 + TypeCode::SBYTE as u8,            // 62
72
    TUPLE_PAIR1_SHORT = TypeCode::TUPLE_PAIR1 as u8 + TypeCode::SSHORT as u8,          // 63
73
    TUPLE_PAIR1_INT = TypeCode::TUPLE_PAIR1 as u8 + TypeCode::SINT as u8,              // 64
74
    TUPLE_PAIR1_LONG = TypeCode::TUPLE_PAIR1 as u8 + TypeCode::SLONG as u8,            // 65
75
    TUPLE_PAIR1_BIGINT = TypeCode::TUPLE_PAIR1 as u8 + TypeCode::SBIGINT as u8,        // 66
76
    TUPLE_PAIR1_GROUP_ELEMENT = TypeCode::TUPLE_PAIR1 as u8 + TypeCode::SGROUP_ELEMENT as u8, // 67
77
    TUPLE_PAIR1_SIGMAPROP = TypeCode::TUPLE_PAIR1 as u8 + TypeCode::SSIGMAPROP as u8,  // 68
78

79
    TUPLE_TRIPLE = Self::TUPLE_PAIR2, // 72
80

81
    TUPLE_PAIR2_BOOL = TypeCode::TUPLE_PAIR2 + TypeCode::SBOOLEAN as u8, // 73
82
    TUPLE_PAIR2_BYTE = TypeCode::TUPLE_PAIR2 + TypeCode::SBYTE as u8,    // 74
83
    TUPLE_PAIR2_SHORT = TypeCode::TUPLE_PAIR2 + TypeCode::SSHORT as u8,  // 75
84
    TUPLE_PAIR2_INT = TypeCode::TUPLE_PAIR2 + TypeCode::SINT as u8,      // 76
85
    TUPLE_PAIR2_LONG = TypeCode::TUPLE_PAIR2 + TypeCode::SLONG as u8,    // 77
86
    TUPLE_PAIR2_BIGINT = TypeCode::TUPLE_PAIR2 + TypeCode::SBIGINT as u8, // 78
87
    TUPLE_PAIR2_GROUP_ELEMENT = TypeCode::TUPLE_PAIR2 + TypeCode::SGROUP_ELEMENT as u8, // 79
88
    TUPLE_PAIR2_SIGMAPROP = TypeCode::TUPLE_PAIR2 + TypeCode::SSIGMAPROP as u8, // 80
89

90
    TUPLE_QUADRUPLE = Self::TUPLE_PAIR_SYMMETRIC, // 84
91

92
    TUPLE_PAIR_SYMMETRIC_BOOL = TypeCode::TUPLE_PAIR_SYMMETRIC + TypeCode::SBOOLEAN as u8, // 85
93
    TUPLE_PAIR_SYMMETRIC_BYTE = TypeCode::TUPLE_PAIR_SYMMETRIC + TypeCode::SBYTE as u8,    // 86
94
    TUPLE_PAIR_SYMMETRIC_SHORT = TypeCode::TUPLE_PAIR_SYMMETRIC + TypeCode::SSHORT as u8,  // 87
95
    TUPLE_PAIR_SYMMETRIC_INT = TypeCode::TUPLE_PAIR_SYMMETRIC + TypeCode::SINT as u8,      // 88
96
    TUPLE_PAIR_SYMMETRIC_LONG = TypeCode::TUPLE_PAIR_SYMMETRIC + TypeCode::SLONG as u8,    // 89
97
    TUPLE_PAIR_SYMMETRIC_BIGINT = TypeCode::TUPLE_PAIR_SYMMETRIC + TypeCode::SBIGINT as u8, // 90
98
    TUPLE_PAIR_SYMMETRIC_GROUP_ELEMENT =
99
        TypeCode::TUPLE_PAIR_SYMMETRIC + TypeCode::SGROUP_ELEMENT as u8, // 91
100
    TUPLE_PAIR_SYMMETRIC_SIGMAPROP = TypeCode::TUPLE_PAIR_SYMMETRIC + TypeCode::SSIGMAPROP as u8, // 92
101

102
    TUPLE = (TypeCode::MAX_PRIM_TYPECODE + 1) * 8, // 12 * 8 = 96
103

104
    SANY = 97,
105
    SUNIT = 98,
106
    SBOX = 99,
107
    SAVL_TREE = 100,
108
    SCONTEXT = 101,
109
    // SSTRING = 102,
110
    STYPE_VAR = 103,
111
    SHEADER = 104,
112
    SPRE_HEADER = 105,
113
    SGLOBAL = 106,
114
}
115

116
impl TypeCode {
117
    /// SFunc types occupy remaining space of byte values [FirstFuncType .. 255]
118
    #[allow(dead_code)]
119
    const FIRST_FUNC_TYPE: u8 = OpCode::LAST_DATA_TYPE.value();
120
    #[allow(dead_code)]
121
    const LAST_FUNC_TYPE: u8 = 255;
122

123
    /// Type code of the last valid prim type so that (1 to LastPrimTypeCode) is a range of valid codes.
124
    #[allow(dead_code)]
125
    const LAST_PRIM_TYPECODE: u8 = 8;
126

127
    /// Upper limit of the interval of valid type codes for primitive types
128
    const MAX_PRIM_TYPECODE: u8 = 11;
129

130
    const COLLECTION_CONSTR_ID: u8 = 1;
131

132
    const NESTED_COLLECTION_CONSTS_ID: u8 = 2;
133
    const NESTED_COLL: u8 =
134
        (TypeCode::MAX_PRIM_TYPECODE + 1) * TypeCode::NESTED_COLLECTION_CONSTS_ID; // 12 * 2 = 24
135

136
    const OPTION_CONSTR_ID: u8 = 3;
137
    const OPTION_COLLECTION_TYPE_CONSTR_ID: u8 = 4;
138
    const OPTION_COLLECTION: u8 =
139
        (TypeCode::MAX_PRIM_TYPECODE + 1) * TypeCode::OPTION_COLLECTION_TYPE_CONSTR_ID; // 12 * 4 = 48
140

141
    const TUPLE_PAIR1_CONSTR_ID: u8 = 5;
142

143
    const TUPLE_PAIR2_CONSTR_ID: u8 = 6;
144
    const TUPLE_PAIR2: u8 = (TypeCode::MAX_PRIM_TYPECODE + 1) * TypeCode::TUPLE_PAIR2_CONSTR_ID; // 12 * 6 = 72
145

146
    const TUPLE_PAIR_SYMMETRIC_TYPE_CONSTR_ID: u8 = 7;
147
    const TUPLE_PAIR_SYMMETRIC: u8 =
148
        (TypeCode::MAX_PRIM_TYPECODE + 1) * TypeCode::TUPLE_PAIR_SYMMETRIC_TYPE_CONSTR_ID; // 12 * 7 = 84
149

150
    /// Parse type code from byte
151
    pub(crate) fn parse(b: u8) -> Result<Self, SigmaParsingError> {
9✔
152
        match FromPrimitive::from_u8(b) {
9✔
153
            Some(t) => Ok(t),
9✔
154
            None => Err(SigmaParsingError::InvalidTypeCode(b)),
1✔
155
        }
156
    }
157

158
    pub(crate) const fn value(&self) -> u8 {
8✔
159
        *self as u8
10✔
160
    }
161
}
162

163
impl SigmaSerializable for TypeCode {
164
    fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult {
8✔
165
        w.put_u8(self.value())?;
10✔
166
        Ok(())
8✔
167
    }
168

169
    fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> Result<Self, SigmaParsingError> {
15✔
170
        let b = r.get_u8()?;
15✔
171
        Self::parse(b)
15✔
172
    }
173
}
174

175
impl SType {
176
    /// Parse type from byte stream. This function should be used instead of
177
    /// `sigma_parse` when type code is already read for look-ahead
178
    pub(crate) fn parse_with_type_code<R: SigmaByteRead>(
13✔
179
        r: &mut R,
180
        c: TypeCode,
181
    ) -> Result<Self, SigmaParsingError> {
182
        use SType::*;
183
        Ok(match c {
26✔
184
            TypeCode::SBOOLEAN => SBoolean,
8✔
185
            TypeCode::SBYTE => SByte,
8✔
186
            TypeCode::SSHORT => SShort,
7✔
187
            TypeCode::SINT => SInt,
12✔
188
            TypeCode::SLONG => SLong,
10✔
189
            TypeCode::SBIGINT => SBigInt,
11✔
190
            TypeCode::SGROUP_ELEMENT => SGroupElement,
8✔
191
            TypeCode::SSIGMAPROP => SSigmaProp,
8✔
192

193
            TypeCode::COLL => SColl(SType::sigma_parse(r)?.into()),
4✔
194
            TypeCode::COLL_BOOL => SColl(SBoolean.into()),
6✔
195
            TypeCode::COLL_BYTE => SColl(SByte.into()),
8✔
196
            TypeCode::COLL_SHORT => SColl(SShort.into()),
6✔
197
            TypeCode::COLL_INT => SColl(SInt.into()),
6✔
198
            TypeCode::COLL_LONG => SColl(SLong.into()),
7✔
199
            TypeCode::COLL_BIGINT => SColl(SBigInt.into()),
6✔
200
            TypeCode::COLL_GROUP_ELEMENT => SColl(SGroupElement.into()),
6✔
201
            TypeCode::COLL_SIGMAPROP => SColl(SSigmaProp.into()),
6✔
202

203
            TypeCode::NESTED_COLL_BOOL => SColl(SColl(SBoolean.into()).into()),
1✔
204
            TypeCode::NESTED_COLL_BYTE => SColl(SColl(SByte.into()).into()),
6✔
UNCOV
205
            TypeCode::NESTED_COLL_SHORT => SColl(SColl(SShort.into()).into()),
×
206
            TypeCode::NESTED_COLL_INT => SColl(SColl(SInt.into()).into()),
1✔
UNCOV
207
            TypeCode::NESTED_COLL_LONG => SColl(SColl(SLong.into()).into()),
×
208
            TypeCode::NESTED_COLL_BIGINT => SColl(SColl(SBigInt.into()).into()),
1✔
UNCOV
209
            TypeCode::NESTED_COLL_GROUP_ELEMENT => SColl(SColl(SGroupElement.into()).into()),
×
210
            TypeCode::NESTED_COLL_SIGMAPROP => SColl(SColl(SSigmaProp.into()).into()),
1✔
211

212
            TypeCode::OPTION => SOption(SType::sigma_parse(r)?.into()),
2✔
213
            TypeCode::OPTION_BOOL => SOption(SBoolean.into()),
1✔
214
            TypeCode::OPTION_BYTE => SOption(SByte.into()),
1✔
215
            TypeCode::OPTION_SHORT => SOption(SShort.into()),
1✔
216
            TypeCode::OPTION_INT => SOption(SInt.into()),
1✔
217
            TypeCode::OPTION_LONG => SOption(SLong.into()),
1✔
218
            TypeCode::OPTION_BIGINT => SOption(SBigInt.into()),
1✔
219
            TypeCode::OPTION_GROUP_ELEMENT => SOption(SGroupElement.into()),
1✔
220
            TypeCode::OPTION_SIGMAPROP => SOption(SSigmaProp.into()),
1✔
221

222
            TypeCode::OPTION_COLL_BOOL => SOption(SColl(SBoolean.into()).into()),
1✔
223
            TypeCode::OPTION_COLL_BYTE => SOption(SColl(SByte.into()).into()),
1✔
224
            TypeCode::OPTION_COLL_SHORT => SOption(SColl(SShort.into()).into()),
×
225
            TypeCode::OPTION_COLL_INT => SOption(SColl(SInt.into()).into()),
×
226
            TypeCode::OPTION_COLL_LONG => SOption(SColl(SLong.into()).into()),
1✔
UNCOV
227
            TypeCode::OPTION_COLL_BIGINT => SOption(SColl(SBigInt.into()).into()),
×
228
            TypeCode::OPTION_COLL_GROUP_ELEMENT => SOption(SColl(SGroupElement.into()).into()),
×
229
            TypeCode::OPTION_COLL_SIGMAPROP => SOption(SColl(SSigmaProp.into()).into()),
1✔
230

231
            TypeCode::TUPLE_PAIR1 => STuple(stuple::STuple::pair(
12✔
232
                SType::sigma_parse(r)?,
12✔
233
                SType::sigma_parse(r)?,
12✔
234
            )),
235
            TypeCode::TUPLE_PAIR1_BOOL => {
×
236
                STuple(stuple::STuple::pair(SBoolean, SType::sigma_parse(r)?))
5✔
237
            }
238
            TypeCode::TUPLE_PAIR1_BYTE => {
×
239
                STuple(stuple::STuple::pair(SByte, SType::sigma_parse(r)?))
6✔
240
            }
241
            TypeCode::TUPLE_PAIR1_SHORT => {
×
242
                STuple(stuple::STuple::pair(SShort, SType::sigma_parse(r)?))
5✔
243
            }
244
            TypeCode::TUPLE_PAIR1_INT => STuple(stuple::STuple::pair(SInt, SType::sigma_parse(r)?)),
6✔
245
            TypeCode::TUPLE_PAIR1_LONG => {
×
246
                STuple(stuple::STuple::pair(SLong, SType::sigma_parse(r)?))
7✔
247
            }
248
            TypeCode::TUPLE_PAIR1_BIGINT => {
×
249
                STuple(stuple::STuple::pair(SBigInt, SType::sigma_parse(r)?))
5✔
250
            }
251
            TypeCode::TUPLE_PAIR1_GROUP_ELEMENT => {
×
252
                STuple(stuple::STuple::pair(SGroupElement, SType::sigma_parse(r)?))
5✔
253
            }
254
            TypeCode::TUPLE_PAIR1_SIGMAPROP => {
×
255
                STuple(stuple::STuple::pair(SSigmaProp, SType::sigma_parse(r)?))
5✔
256
            }
257

258
            TypeCode::TUPLE_TRIPLE => STuple(stuple::STuple::triple(
12✔
259
                SType::sigma_parse(r)?,
12✔
260
                SType::sigma_parse(r)?,
12✔
261
                SType::sigma_parse(r)?,
12✔
262
            )),
263

264
            TypeCode::TUPLE_PAIR2_BOOL => {
×
265
                STuple(stuple::STuple::pair(SType::sigma_parse(r)?, SBoolean))
6✔
266
            }
267
            TypeCode::TUPLE_PAIR2_BYTE => {
×
268
                STuple(stuple::STuple::pair(SType::sigma_parse(r)?, SByte))
8✔
269
            }
270
            TypeCode::TUPLE_PAIR2_SHORT => {
×
271
                STuple(stuple::STuple::pair(SType::sigma_parse(r)?, SShort))
10✔
272
            }
273
            TypeCode::TUPLE_PAIR2_INT => STuple(stuple::STuple::pair(SType::sigma_parse(r)?, SInt)),
8✔
274
            TypeCode::TUPLE_PAIR2_LONG => {
×
275
                STuple(stuple::STuple::pair(SType::sigma_parse(r)?, SLong))
8✔
276
            }
277
            TypeCode::TUPLE_PAIR2_BIGINT => {
×
278
                STuple(stuple::STuple::pair(SType::sigma_parse(r)?, SBigInt))
6✔
279
            }
280
            TypeCode::TUPLE_PAIR2_GROUP_ELEMENT => {
×
281
                STuple(stuple::STuple::pair(SType::sigma_parse(r)?, SGroupElement))
8✔
282
            }
283
            TypeCode::TUPLE_PAIR2_SIGMAPROP => {
×
284
                STuple(stuple::STuple::pair(SType::sigma_parse(r)?, SSigmaProp))
8✔
285
            }
286

287
            TypeCode::TUPLE_QUADRUPLE => STuple(stuple::STuple::quadruple(
12✔
288
                SType::sigma_parse(r)?,
12✔
289
                SType::sigma_parse(r)?,
12✔
290
                SType::sigma_parse(r)?,
12✔
291
                SType::sigma_parse(r)?,
12✔
292
            )),
293

294
            TypeCode::TUPLE_PAIR_SYMMETRIC_BOOL => STuple(stuple::STuple::pair(SBoolean, SBoolean)),
3✔
295
            TypeCode::TUPLE_PAIR_SYMMETRIC_BYTE => STuple(stuple::STuple::pair(SByte, SByte)),
3✔
296
            TypeCode::TUPLE_PAIR_SYMMETRIC_SHORT => STuple(stuple::STuple::pair(SShort, SShort)),
×
297
            TypeCode::TUPLE_PAIR_SYMMETRIC_INT => STuple(stuple::STuple::pair(SInt, SInt)),
5✔
298
            TypeCode::TUPLE_PAIR_SYMMETRIC_LONG => STuple(stuple::STuple::pair(SLong, SLong)),
4✔
299
            TypeCode::TUPLE_PAIR_SYMMETRIC_BIGINT => STuple(stuple::STuple::pair(SBigInt, SBigInt)),
3✔
300
            TypeCode::TUPLE_PAIR_SYMMETRIC_GROUP_ELEMENT => {
×
301
                STuple(stuple::STuple::pair(SGroupElement, SGroupElement))
5✔
302
            }
303
            TypeCode::TUPLE_PAIR_SYMMETRIC_SIGMAPROP => {
×
304
                STuple(stuple::STuple::pair(SSigmaProp, SSigmaProp))
4✔
305
            }
306

307
            TypeCode::TUPLE => {
×
308
                let len = r.get_u8()?;
2✔
309
                let mut items = Vec::with_capacity(len as usize);
1✔
310
                for _ in 0..len {
2✔
311
                    items.push(SType::sigma_parse(r)?);
2✔
312
                }
313
                SType::STuple(
1✔
314
                    items
2✔
315
                        .try_into()
×
316
                        .map_err(|_| SigmaParsingError::TupleItemsOutOfBounds(len as usize))?,
×
317
                )
318
            }
319

320
            TypeCode::SANY => SAny,
2✔
321
            TypeCode::SUNIT => SUnit,
1✔
322
            TypeCode::SBOX => SBox,
4✔
323
            TypeCode::SAVL_TREE => SAvlTree,
2✔
324
            TypeCode::SCONTEXT => SContext,
1✔
325
            TypeCode::STYPE_VAR => STypeVar(stype_param::STypeVar::sigma_parse(r)?),
2✔
326
            TypeCode::SHEADER => SHeader,
1✔
327
            TypeCode::SPRE_HEADER => SPreHeader,
1✔
328
            TypeCode::SGLOBAL => SGlobal,
1✔
329
        })
330
    }
331
}
332

333
/// Each SType is serialized to array of bytes by:
334
/// - emitting typeCode of each node (see special case for collections below)
335
/// - then recursively serializing subtrees from left to right on each level
336
/// - for each collection of primitive type there is special type code to emit single byte instead of two bytes
337
///
338
/// Types code intervals
339
/// - (1 .. MaxPrimTypeCode)  // primitive types
340
/// - (CollectionTypeCode .. CollectionTypeCode + MaxPrimTypeCode) // collections of primitive types
341
/// - (MaxCollectionTypeCode ..)  // Other types
342
///
343
/// Collection of non-primitive type is serialized as (CollectionTypeCode, serialize(elementType))
344
impl SigmaSerializable for SType {
345
    fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult {
8✔
346
        // for reference see http://github.com/ScorexFoundation/sigmastate-interpreter/blob/25251c1313b0131835f92099f02cef8a5d932b5e/sigmastate/src/main/scala/sigmastate/serialization/TypeSerializer.scala#L25-L25
347
        use SType::*;
348
        match self {
8✔
349
            SType::SFunc(_) => Err(SigmaSerializationError::NotSupported(
×
350
                "SFunc serialization is no supported".to_string(),
×
351
            )),
352
            SType::SAny => TypeCode::SANY.sigma_serialize(w),
1✔
353
            SType::SUnit => TypeCode::SUNIT.sigma_serialize(w),
×
354
            SType::SBoolean => TypeCode::SBOOLEAN.sigma_serialize(w),
6✔
355
            SType::SByte => TypeCode::SBYTE.sigma_serialize(w),
5✔
356
            SType::SShort => TypeCode::SSHORT.sigma_serialize(w),
5✔
357
            SType::SInt => TypeCode::SINT.sigma_serialize(w),
8✔
358
            SType::SLong => TypeCode::SLONG.sigma_serialize(w),
6✔
359
            SType::SBigInt => TypeCode::SBIGINT.sigma_serialize(w),
8✔
360
            SType::SGroupElement => TypeCode::SGROUP_ELEMENT.sigma_serialize(w),
5✔
361
            SType::SSigmaProp => TypeCode::SSIGMAPROP.sigma_serialize(w),
7✔
362
            SType::SBox => TypeCode::SBOX.sigma_serialize(w),
2✔
363
            SType::SAvlTree => TypeCode::SAVL_TREE.sigma_serialize(w),
1✔
364
            SType::SContext => TypeCode::SCONTEXT.sigma_serialize(w),
1✔
365
            SType::SHeader => TypeCode::SHEADER.sigma_serialize(w),
1✔
366
            SType::SPreHeader => TypeCode::SPRE_HEADER.sigma_serialize(w),
1✔
367
            SType::SGlobal => TypeCode::SGLOBAL.sigma_serialize(w),
1✔
368
            SOption(elem_type) => match &**elem_type {
1✔
369
                SBoolean => TypeCode::OPTION_BOOL.sigma_serialize(w),
1✔
370
                SByte => TypeCode::OPTION_BYTE.sigma_serialize(w),
1✔
371
                SShort => TypeCode::OPTION_SHORT.sigma_serialize(w),
1✔
372
                SInt => TypeCode::OPTION_INT.sigma_serialize(w),
1✔
373
                SLong => TypeCode::OPTION_LONG.sigma_serialize(w),
1✔
374
                SBigInt => TypeCode::OPTION_BIGINT.sigma_serialize(w),
1✔
375
                SGroupElement => TypeCode::OPTION_GROUP_ELEMENT.sigma_serialize(w),
1✔
376
                SSigmaProp => TypeCode::OPTION_SIGMAPROP.sigma_serialize(w),
1✔
377
                SColl(inner_elem_type) => match &**inner_elem_type {
1✔
378
                    SBoolean => TypeCode::OPTION_COLL_BOOL.sigma_serialize(w),
1✔
379
                    SByte => TypeCode::OPTION_COLL_BYTE.sigma_serialize(w),
×
380
                    SShort => TypeCode::OPTION_COLL_SHORT.sigma_serialize(w),
×
381
                    SInt => TypeCode::OPTION_COLL_INT.sigma_serialize(w),
×
382
                    SLong => TypeCode::OPTION_COLL_LONG.sigma_serialize(w),
1✔
UNCOV
383
                    SBigInt => TypeCode::OPTION_COLL_BIGINT.sigma_serialize(w),
×
384
                    SGroupElement => TypeCode::OPTION_COLL_GROUP_ELEMENT.sigma_serialize(w),
×
385
                    SSigmaProp => TypeCode::OPTION_COLL_SIGMAPROP.sigma_serialize(w),
1✔
386
                    STypeVar(_) | SAny | SUnit | SBox | SAvlTree | SOption(_) | SColl(_)
×
387
                    | STuple(_) | SFunc(_) | SContext | SHeader | SPreHeader | SGlobal => {
×
388
                        // if not "embeddable" type fallback to generic Option type code following
389
                        // elem type code
390
                        TypeCode::OPTION.sigma_serialize(w)?;
1✔
391
                        elem_type.sigma_serialize(w)
1✔
392
                    }
393
                },
394
                STypeVar(_) | SAny | SUnit | SBox | SAvlTree | SOption(_) | STuple(_)
×
395
                | SFunc(_) | SContext | SHeader | SPreHeader | SGlobal => {
×
396
                    // if not "embeddable" type fallback to generic Option type code following
397
                    // elem type code
398
                    TypeCode::OPTION.sigma_serialize(w)?;
1✔
399
                    elem_type.sigma_serialize(w)
1✔
400
                }
401
            },
402

403
            SType::SColl(elem_type) => match &**elem_type {
6✔
404
                SBoolean => TypeCode::COLL_BOOL.sigma_serialize(w),
5✔
405
                SByte => TypeCode::COLL_BYTE.sigma_serialize(w),
5✔
406
                SShort => TypeCode::COLL_SHORT.sigma_serialize(w),
6✔
407
                SInt => TypeCode::COLL_INT.sigma_serialize(w),
5✔
408
                SLong => TypeCode::COLL_LONG.sigma_serialize(w),
5✔
409
                SBigInt => TypeCode::COLL_BIGINT.sigma_serialize(w),
5✔
410
                SGroupElement => TypeCode::COLL_GROUP_ELEMENT.sigma_serialize(w),
5✔
411
                SSigmaProp => TypeCode::COLL_SIGMAPROP.sigma_serialize(w),
5✔
412
                SColl(inner_elem_type) => match &**inner_elem_type {
5✔
413
                    SBoolean => TypeCode::NESTED_COLL_BOOL.sigma_serialize(w),
1✔
414
                    SByte => TypeCode::NESTED_COLL_BYTE.sigma_serialize(w),
5✔
UNCOV
415
                    SShort => TypeCode::NESTED_COLL_SHORT.sigma_serialize(w),
×
416
                    SInt => TypeCode::NESTED_COLL_INT.sigma_serialize(w),
1✔
UNCOV
417
                    SLong => TypeCode::NESTED_COLL_LONG.sigma_serialize(w),
×
418
                    SBigInt => TypeCode::NESTED_COLL_BIGINT.sigma_serialize(w),
1✔
UNCOV
419
                    SGroupElement => TypeCode::NESTED_COLL_GROUP_ELEMENT.sigma_serialize(w),
×
420
                    SSigmaProp => TypeCode::NESTED_COLL_SIGMAPROP.sigma_serialize(w),
1✔
421
                    STypeVar(_) | SAny | SUnit | SBox | SAvlTree | SOption(_) | SColl(_)
×
422
                    | STuple(_) | SFunc(_) | SContext | SHeader | SPreHeader | SGlobal => {
×
423
                        // if not "embeddable" type fallback to generic Coll type code following
424
                        // elem type code
425
                        TypeCode::COLL.sigma_serialize(w)?;
1✔
426
                        elem_type.sigma_serialize(w)
1✔
427
                    }
428
                },
429
                STypeVar(_) | SAny | SUnit | SBox | SAvlTree | SOption(_) | STuple(_)
×
430
                | SFunc(_) | SContext | SHeader | SPreHeader | SGlobal => {
×
431
                    // if not "embeddable" type fallback to generic Coll type code following
432
                    // elem type code
433
                    TypeCode::COLL.sigma_serialize(w)?;
1✔
434
                    elem_type.sigma_serialize(w)
1✔
435
                }
436
            },
437
            SType::STuple(stuple::STuple { items }) => match items.clone().as_slice() {
5✔
438
                [t1, t2] => match (t1, t2) {
23✔
439
                    (SBoolean, SBoolean) => TypeCode::TUPLE_PAIR_SYMMETRIC_BOOL.sigma_serialize(w),
6✔
440
                    (SByte, SByte) => TypeCode::TUPLE_PAIR_SYMMETRIC_BYTE.sigma_serialize(w),
6✔
441
                    (SInt, SInt) => TypeCode::TUPLE_PAIR_SYMMETRIC_INT.sigma_serialize(w),
6✔
442
                    (SLong, SLong) => TypeCode::TUPLE_PAIR_SYMMETRIC_LONG.sigma_serialize(w),
6✔
443
                    (SBigInt, SBigInt) => TypeCode::TUPLE_PAIR_SYMMETRIC_BIGINT.sigma_serialize(w),
6✔
444
                    (SGroupElement, SGroupElement) => {
×
445
                        TypeCode::TUPLE_PAIR_SYMMETRIC_GROUP_ELEMENT.sigma_serialize(w)
8✔
446
                    }
447
                    (SSigmaProp, SSigmaProp) => {
×
448
                        TypeCode::TUPLE_PAIR_SYMMETRIC_SIGMAPROP.sigma_serialize(w)
6✔
449
                    }
450

451
                    (SBoolean, t2) => {
4✔
452
                        TypeCode::TUPLE_PAIR1_BOOL.sigma_serialize(w)?;
8✔
453
                        t2.sigma_serialize(w)
8✔
454
                    }
455
                    (SByte, t2) => {
4✔
456
                        TypeCode::TUPLE_PAIR1_BYTE.sigma_serialize(w)?;
8✔
457
                        t2.sigma_serialize(w)
8✔
458
                    }
459
                    (SShort, t2) => {
5✔
460
                        TypeCode::TUPLE_PAIR1_SHORT.sigma_serialize(w)?;
10✔
461
                        t2.sigma_serialize(w)
10✔
462
                    }
463
                    (SInt, t2) => {
5✔
464
                        TypeCode::TUPLE_PAIR1_INT.sigma_serialize(w)?;
10✔
465
                        t2.sigma_serialize(w)
10✔
466
                    }
467
                    (SLong, t2) => {
5✔
468
                        TypeCode::TUPLE_PAIR1_LONG.sigma_serialize(w)?;
10✔
469
                        t2.sigma_serialize(w)
10✔
470
                    }
471
                    (SBigInt, t2) => {
4✔
472
                        TypeCode::TUPLE_PAIR1_BIGINT.sigma_serialize(w)?;
8✔
473
                        t2.sigma_serialize(w)
8✔
474
                    }
475
                    (SGroupElement, t2) => {
4✔
476
                        TypeCode::TUPLE_PAIR1_GROUP_ELEMENT.sigma_serialize(w)?;
8✔
477
                        t2.sigma_serialize(w)
8✔
478
                    }
479
                    (SSigmaProp, t2) => {
4✔
480
                        TypeCode::TUPLE_PAIR1_SIGMAPROP.sigma_serialize(w)?;
9✔
481
                        t2.sigma_serialize(w)
10✔
482
                    }
483

484
                    (t1, SBoolean) => {
3✔
485
                        TypeCode::TUPLE_PAIR2_BOOL.sigma_serialize(w)?;
6✔
486
                        t1.sigma_serialize(w)
6✔
487
                    }
488
                    (t1, SByte) => {
4✔
489
                        TypeCode::TUPLE_PAIR2_BYTE.sigma_serialize(w)?;
8✔
490
                        t1.sigma_serialize(w)
8✔
491
                    }
492
                    (t1, SShort) => {
4✔
493
                        TypeCode::TUPLE_PAIR2_SHORT.sigma_serialize(w)?;
8✔
494
                        t1.sigma_serialize(w)
8✔
495
                    }
496
                    (t1, SInt) => {
3✔
497
                        TypeCode::TUPLE_PAIR2_INT.sigma_serialize(w)?;
6✔
498
                        t1.sigma_serialize(w)
6✔
499
                    }
500
                    (t1, SLong) => {
4✔
501
                        TypeCode::TUPLE_PAIR2_LONG.sigma_serialize(w)?;
8✔
502
                        t1.sigma_serialize(w)
8✔
503
                    }
504
                    (t1, SBigInt) => {
3✔
505
                        TypeCode::TUPLE_PAIR2_BIGINT.sigma_serialize(w)?;
6✔
506
                        t1.sigma_serialize(w)
6✔
507
                    }
508
                    (t1, SGroupElement) => {
3✔
509
                        TypeCode::TUPLE_PAIR2_GROUP_ELEMENT.sigma_serialize(w)?;
6✔
510
                        t1.sigma_serialize(w)
6✔
511
                    }
512
                    (t1, SSigmaProp) => {
4✔
513
                        TypeCode::TUPLE_PAIR2_SIGMAPROP.sigma_serialize(w)?;
8✔
514
                        t1.sigma_serialize(w)
8✔
515
                    }
516
                    (
517
                        STypeVar(_) | SAny | SUnit | SBox | SAvlTree | SOption(_) | SColl(_)
×
518
                        | STuple(_) | SFunc(_) | SContext | SHeader | SPreHeader | SGlobal,
×
519
                        STypeVar(_) | SAny | SUnit | SBox | SAvlTree | SOption(_) | SColl(_)
×
520
                        | STuple(_) | SFunc(_) | SContext | SHeader | SPreHeader | SGlobal,
×
521
                    ) => {
×
522
                        // Pair of non-primitive types (`(SBox, SAvlTree)`, `((Int, Byte), (Boolean,Box))`, etc.)
523
                        TypeCode::TUPLE_PAIR1.sigma_serialize(w)?;
4✔
524
                        t1.sigma_serialize(w)?;
8✔
525
                        t2.sigma_serialize(w)
8✔
526
                    }
527
                },
528
                [t1, t2, t3] => {
10✔
529
                    TypeCode::TUPLE_TRIPLE.sigma_serialize(w)?;
10✔
530
                    t1.sigma_serialize(w)?;
10✔
531
                    t2.sigma_serialize(w)?;
10✔
532
                    t3.sigma_serialize(w)
10✔
533
                }
534
                [t1, t2, t3, t4] => {
10✔
535
                    TypeCode::TUPLE_QUADRUPLE.sigma_serialize(w)?;
10✔
536
                    t1.sigma_serialize(w)?;
12✔
537
                    t2.sigma_serialize(w)?;
11✔
538
                    t3.sigma_serialize(w)?;
12✔
539
                    t4.sigma_serialize(w)
13✔
540
                }
541
                _ => {
×
542
                    TypeCode::TUPLE.sigma_serialize(w)?;
2✔
543
                    w.put_u8(items.len() as u8)?;
2✔
544
                    items.iter().try_for_each(|i| i.sigma_serialize(w))
4✔
545
                }
546
            },
547

548
            SType::STypeVar(tv) => {
1✔
549
                TypeCode::STYPE_VAR.sigma_serialize(w)?;
11✔
550
                tv.sigma_serialize(w)
1✔
551
            }
552
        }
553
    }
554

555
    fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> Result<Self, SigmaParsingError> {
9✔
556
        // for reference see http://github.com/ScorexFoundation/sigmastate-interpreter/blob/25251c1313b0131835f92099f02cef8a5d932b5e/sigmastate/src/main/scala/sigmastate/serialization/TypeSerializer.scala#L118-L118
557
        let c = TypeCode::sigma_parse(r)?;
11✔
558
        Self::parse_with_type_code(r, c)
9✔
559
    }
560
}
561

562
#[cfg(test)]
563
#[cfg(feature = "arbitrary")]
564
#[allow(clippy::panic)]
565
mod tests {
566
    use super::*;
567
    use crate::serialization::sigma_serialize_roundtrip;
568

569
    use proptest::prelude::*;
570

571
    proptest! {
572

573
        #[test]
574
        fn ser_roundtrip(v in any::<SType>()) {
575
            prop_assert_eq![sigma_serialize_roundtrip(&v), v];
576
        }
577
    }
578
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc