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