massa_module_cache/
types.rs

1use massa_models::serialization::{StringDeserializer, StringSerializer};
2use massa_sc_runtime::RuntimeModule;
3use massa_serialization::{
4    Deserializer, SerializeError, Serializer, U64VarIntDeserializer, U64VarIntSerializer,
5};
6use nom::{
7    error::{context, ContextError, ParseError},
8    IResult, Parser,
9};
10use num_enum::{IntoPrimitive, TryFromPrimitive};
11use std::ops::Bound::Included;
12
13/// Main type
14#[derive(Clone)]
15pub enum ModuleInfo {
16    Invalid(String), // contains the error message
17    Module(RuntimeModule),
18    ModuleAndDelta((RuntimeModule, u64)),
19}
20
21#[derive(PartialEq, Eq)]
22/// Metadata type
23pub enum ModuleMetadata {
24    Invalid(String), // contains the error message
25    NotExecuted,
26    Delta(u64),
27}
28
29/// Metadata ID type
30#[derive(IntoPrimitive, Debug, Eq, PartialEq, TryFromPrimitive)]
31#[repr(u64)]
32enum ModuleMetadataId {
33    Invalid = 0u64,
34    NotExecuted = 1u64,
35    Delta = 2u64,
36}
37
38/// Metadata serializer
39pub struct ModuleMetadataSerializer {
40    u64_ser: U64VarIntSerializer,
41    err_msg_ser: StringSerializer<U64VarIntSerializer, u64>,
42}
43
44impl ModuleMetadataSerializer {
45    pub fn new() -> Self {
46        Self {
47            u64_ser: U64VarIntSerializer::new(),
48            err_msg_ser: StringSerializer::new(U64VarIntSerializer::new()),
49        }
50    }
51}
52
53impl Default for ModuleMetadataSerializer {
54    fn default() -> Self {
55        Self::new()
56    }
57}
58
59impl Serializer<ModuleMetadata> for ModuleMetadataSerializer {
60    fn serialize(
61        &self,
62        value: &ModuleMetadata,
63        buffer: &mut Vec<u8>,
64    ) -> Result<(), SerializeError> {
65        match value {
66            ModuleMetadata::NotExecuted => self
67                .u64_ser
68                .serialize(&u64::from(ModuleMetadataId::NotExecuted), buffer)?,
69            ModuleMetadata::Invalid(err_msg) => {
70                self.u64_ser
71                    .serialize(&u64::from(ModuleMetadataId::Invalid), buffer)?;
72                self.err_msg_ser.serialize(err_msg, buffer)?;
73            }
74            ModuleMetadata::Delta(delta) => {
75                self.u64_ser
76                    .serialize(&u64::from(ModuleMetadataId::Delta), buffer)?;
77                self.u64_ser.serialize(delta, buffer)?;
78            }
79        }
80        Ok(())
81    }
82}
83
84/// Metadata deserializer
85pub struct ModuleMetadataDeserializer {
86    id_deser: U64VarIntDeserializer,
87    delta_deser: U64VarIntDeserializer,
88    err_msg_deser: StringDeserializer<U64VarIntDeserializer, u64>,
89}
90
91impl ModuleMetadataDeserializer {
92    pub fn new() -> Self {
93        Self {
94            id_deser: U64VarIntDeserializer::new(
95                Included(u64::from(ModuleMetadataId::Invalid)),
96                Included(u64::from(ModuleMetadataId::Delta)),
97            ),
98            delta_deser: U64VarIntDeserializer::new(Included(0), Included(u64::MAX)),
99            err_msg_deser: StringDeserializer::new(U64VarIntDeserializer::new(
100                Included(0),
101                Included(u64::MAX),
102            )),
103        }
104    }
105}
106
107impl Default for ModuleMetadataDeserializer {
108    fn default() -> Self {
109        Self::new()
110    }
111}
112
113impl Deserializer<ModuleMetadata> for ModuleMetadataDeserializer {
114    fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
115        &self,
116        buffer: &'a [u8],
117    ) -> IResult<&'a [u8], ModuleMetadata, E> {
118        context("ModuleMetadata", |buffer| {
119            // can unwrap here because the range is defined in the serializer setup
120            let (input, id) = context("ModuleMetadataId", |input| self.id_deser.deserialize(input))
121                .map(|id| ModuleMetadataId::try_from(id).unwrap())
122                .parse(buffer)?;
123            match id {
124                ModuleMetadataId::Invalid => context("ModuleMetadata::Invalid", |input| {
125                    self.err_msg_deser.deserialize(input)
126                })
127                .map(ModuleMetadata::Invalid)
128                .parse(input),
129                ModuleMetadataId::NotExecuted => Ok((input, ModuleMetadata::NotExecuted)),
130                ModuleMetadataId::Delta => context("ModuleMetadata::Delta", |input| {
131                    self.delta_deser.deserialize(input)
132                })
133                .map(ModuleMetadata::Delta)
134                .parse(input),
135            }
136        })
137        .parse(buffer)
138    }
139}