Skip to main content

miden_protocol/note/
note_type.rs

1use core::fmt::Display;
2use core::str::FromStr;
3
4use crate::Felt;
5use crate::errors::NoteError;
6use crate::utils::serde::{
7    ByteReader,
8    ByteWriter,
9    Deserializable,
10    DeserializationError,
11    Serializable,
12};
13
14// NOTE TYPE
15// ================================================================================================
16
17#[derive(Clone, Copy, Debug, PartialEq, Eq)]
18#[repr(u8)]
19pub enum NoteType {
20    /// Notes with this type have only their hash published to the network.
21    Private = Self::PRIVATE,
22
23    /// Notes with this type are fully shared with the network.
24    Public = Self::PUBLIC,
25}
26
27impl NoteType {
28    // Keep these masks in sync with `miden-lib/asm/miden/kernels/tx/tx.masm`
29    pub const PUBLIC: u8 = 0b01;
30    pub const PRIVATE: u8 = 0b10;
31}
32
33// CONVERSIONS FROM NOTE TYPE
34// ================================================================================================
35
36impl From<NoteType> for Felt {
37    fn from(id: NoteType) -> Self {
38        Felt::new(id as u64)
39    }
40}
41
42// CONVERSIONS INTO NOTE TYPE
43// ================================================================================================
44
45impl TryFrom<u8> for NoteType {
46    type Error = NoteError;
47
48    fn try_from(value: u8) -> Result<Self, Self::Error> {
49        match value {
50            Self::PRIVATE => Ok(NoteType::Private),
51            Self::PUBLIC => Ok(NoteType::Public),
52            _ => Err(NoteError::UnknownNoteType(format!("0b{value:b}").into())),
53        }
54    }
55}
56
57impl TryFrom<u16> for NoteType {
58    type Error = NoteError;
59
60    fn try_from(value: u16) -> Result<Self, Self::Error> {
61        Self::try_from(value as u64)
62    }
63}
64
65impl TryFrom<u32> for NoteType {
66    type Error = NoteError;
67
68    fn try_from(value: u32) -> Result<Self, Self::Error> {
69        Self::try_from(value as u64)
70    }
71}
72
73impl TryFrom<u64> for NoteType {
74    type Error = NoteError;
75
76    fn try_from(value: u64) -> Result<Self, Self::Error> {
77        let value: u8 = value
78            .try_into()
79            .map_err(|_| NoteError::UnknownNoteType(format!("0b{value:b}").into()))?;
80        value.try_into()
81    }
82}
83
84impl TryFrom<Felt> for NoteType {
85    type Error = NoteError;
86
87    fn try_from(value: Felt) -> Result<Self, Self::Error> {
88        value.as_canonical_u64().try_into()
89    }
90}
91
92impl FromStr for NoteType {
93    type Err = NoteError;
94
95    fn from_str(s: &str) -> Result<Self, Self::Err> {
96        match s {
97            "private" => Ok(NoteType::Private),
98            "public" => Ok(NoteType::Public),
99            _ => Err(NoteError::UnknownNoteType(s.into())),
100        }
101    }
102}
103
104// SERIALIZATION
105// ================================================================================================
106
107impl Serializable for NoteType {
108    fn write_into<W: ByteWriter>(&self, target: &mut W) {
109        (*self as u8).write_into(target)
110    }
111
112    fn get_size_hint(&self) -> usize {
113        core::mem::size_of::<u8>()
114    }
115}
116
117impl Deserializable for NoteType {
118    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
119        let discriminant = u8::read_from(source)?;
120
121        let note_type = match discriminant {
122            NoteType::PRIVATE => NoteType::Private,
123            NoteType::PUBLIC => NoteType::Public,
124            discriminant => {
125                return Err(DeserializationError::InvalidValue(format!(
126                    "discriminant {discriminant} is not a valid NoteType"
127                )));
128            },
129        };
130
131        Ok(note_type)
132    }
133}
134
135// DISPLAY
136// ================================================================================================
137
138impl Display for NoteType {
139    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
140        match self {
141            NoteType::Private => write!(f, "private"),
142            NoteType::Public => write!(f, "public"),
143        }
144    }
145}
146
147#[test]
148fn test_from_str_note_type() {
149    use assert_matches::assert_matches;
150
151    use crate::alloc::string::ToString;
152
153    for string in ["private", "public"] {
154        let parsed_note_type = NoteType::from_str(string).unwrap();
155        assert_eq!(parsed_note_type.to_string(), string);
156    }
157
158    let public_type_invalid_err = NoteType::from_str("puBlIc").unwrap_err();
159    assert_matches!(public_type_invalid_err, NoteError::UnknownNoteType(_));
160
161    let invalid_type = NoteType::from_str("invalid").unwrap_err();
162    assert_matches!(invalid_type, NoteError::UnknownNoteType(_));
163}