miden_protocol/note/
note_type.rs1use 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#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
18#[repr(u8)]
19pub enum NoteType {
20 #[default]
21 Private = Self::PRIVATE,
23
24 Public = Self::PUBLIC,
26}
27
28impl NoteType {
29 const PRIVATE: u8 = 0;
30 const PUBLIC: u8 = 1;
31
32 pub const fn as_u8(self) -> u8 {
34 self as u8
35 }
36}
37
38impl From<NoteType> for Felt {
42 fn from(note_type: NoteType) -> Self {
43 Felt::from(note_type.as_u8())
44 }
45}
46
47impl TryFrom<u8> for NoteType {
51 type Error = NoteError;
52
53 fn try_from(value: u8) -> Result<Self, Self::Error> {
54 match value {
55 Self::PRIVATE => Ok(NoteType::Private),
56 Self::PUBLIC => Ok(NoteType::Public),
57 _ => Err(NoteError::UnknownNoteType(format!("0b{value:b}").into())),
58 }
59 }
60}
61
62impl TryFrom<Felt> for NoteType {
63 type Error = NoteError;
64
65 fn try_from(value: Felt) -> Result<Self, Self::Error> {
66 let byte = value.as_canonical_u64();
67 Self::try_from(
68 u8::try_from(byte)
69 .map_err(|_| NoteError::UnknownNoteType(format!("0b{byte:b}").into()))?,
70 )
71 }
72}
73
74impl Display for NoteType {
78 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
79 match self {
80 NoteType::Private => write!(f, "private"),
81 NoteType::Public => write!(f, "public"),
82 }
83 }
84}
85
86impl FromStr for NoteType {
87 type Err = NoteError;
88
89 fn from_str(s: &str) -> Result<Self, Self::Err> {
90 match s {
91 "private" => Ok(NoteType::Private),
92 "public" => Ok(NoteType::Public),
93 _ => Err(NoteError::UnknownNoteType(s.into())),
94 }
95 }
96}
97
98impl Serializable for NoteType {
102 fn write_into<W: ByteWriter>(&self, target: &mut W) {
103 (*self as u8).write_into(target)
104 }
105
106 fn get_size_hint(&self) -> usize {
107 core::mem::size_of::<u8>()
108 }
109}
110
111impl Deserializable for NoteType {
112 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
113 let discriminant = u8::read_from(source)?;
114
115 let note_type = match discriminant {
116 NoteType::PRIVATE => NoteType::Private,
117 NoteType::PUBLIC => NoteType::Public,
118 discriminant => {
119 return Err(DeserializationError::InvalidValue(format!(
120 "discriminant {discriminant} is not a valid NoteType"
121 )));
122 },
123 };
124
125 Ok(note_type)
126 }
127}
128
129#[cfg(test)]
133mod tests {
134 use assert_matches::assert_matches;
135
136 use super::*;
137 use crate::alloc::string::ToString;
138
139 #[rstest::rstest]
140 #[case::private(NoteType::Private)]
141 #[case::public(NoteType::Public)]
142 #[test]
143 fn test_note_type_roundtrip(#[case] note_type: NoteType) -> anyhow::Result<()> {
144 assert_eq!(note_type, note_type.to_string().parse()?);
146
147 assert_eq!(note_type, NoteType::read_from_bytes(¬e_type.to_bytes())?);
149
150 assert_eq!(note_type, NoteType::try_from(note_type.as_u8())?);
152
153 assert_eq!(note_type, NoteType::try_from(Felt::from(note_type))?);
155
156 Ok(())
157 }
158
159 #[test]
160 fn test_from_str_note_type() {
161 for string in ["private", "public"] {
162 let parsed_note_type = NoteType::from_str(string).unwrap();
163 assert_eq!(parsed_note_type.to_string(), string);
164 }
165
166 let public_type_invalid_err = NoteType::from_str("puBlIc").unwrap_err();
167 assert_matches!(public_type_invalid_err, NoteError::UnknownNoteType(_));
168
169 let invalid_type = NoteType::from_str("invalid").unwrap_err();
170 assert_matches!(invalid_type, NoteError::UnknownNoteType(_));
171 }
172}