1#![no_std]
7#![deny(warnings)]
8
9extern crate alloc;
10
11use alloc::vec::Vec;
12
13pub use miden_field::Felt;
14pub use miden_field_repr_derive::DeriveFromFeltRepr as FromFeltRepr;
16pub use miden_field_repr_derive::DeriveToFeltRepr as ToFeltRepr;
18
19pub struct FeltReader<'a> {
21 data: &'a [Felt],
22 pos: usize,
23}
24
25impl<'a> FeltReader<'a> {
26 #[inline(always)]
28 pub fn new(data: &'a [Felt]) -> Self {
29 Self { data, pos: 0 }
30 }
31
32 #[inline(always)]
38 pub fn read(&mut self) -> Felt {
39 assert!(self.pos < self.data.len(), "FeltReader: no more elements to read");
40 let felt = self.data[self.pos];
41 self.pos += 1;
42 felt
43 }
44}
45
46pub struct FeltWriter<'a> {
48 data: &'a mut Vec<Felt>,
49}
50
51impl<'a> FeltWriter<'a> {
52 #[inline(always)]
54 pub fn new(data: &'a mut Vec<Felt>) -> Self {
55 Self { data }
56 }
57
58 #[inline(always)]
60 pub fn write(&mut self, felt: Felt) {
61 self.data.push(felt);
62 }
63}
64
65pub trait FromFeltRepr: Sized {
67 fn from_felt_repr(reader: &mut FeltReader<'_>) -> Self;
69}
70
71impl FromFeltRepr for Felt {
72 #[inline(always)]
73 fn from_felt_repr(reader: &mut FeltReader<'_>) -> Self {
74 reader.read()
75 }
76}
77
78#[cfg(not(target_family = "wasm"))]
79impl FromFeltRepr for miden_core::Felt {
80 #[inline(always)]
81 fn from_felt_repr(reader: &mut FeltReader<'_>) -> Self {
82 Self::from(reader.read())
83 }
84}
85
86impl FromFeltRepr for u64 {
87 #[inline(always)]
88 fn from_felt_repr(reader: &mut FeltReader<'_>) -> Self {
89 let lo = reader.read().as_u64();
91 assert!(lo <= u32::MAX as u64, "u64: low limb out of range");
92 let hi = reader.read().as_u64();
93 assert!(hi <= u32::MAX as u64, "u64: high limb out of range");
94
95 (hi << 32) | lo
96 }
97}
98
99impl FromFeltRepr for u32 {
100 #[inline(always)]
101 fn from_felt_repr(reader: &mut FeltReader<'_>) -> Self {
102 reader.read().as_u64() as u32
103 }
104}
105
106impl FromFeltRepr for u8 {
107 #[inline(always)]
108 fn from_felt_repr(reader: &mut FeltReader<'_>) -> Self {
109 reader.read().as_u64() as u8
110 }
111}
112
113impl FromFeltRepr for bool {
114 #[inline(always)]
115 fn from_felt_repr(reader: &mut FeltReader<'_>) -> Self {
116 reader.read().as_u64() != 0
117 }
118}
119
120impl<T> FromFeltRepr for Option<T>
126where
127 T: FromFeltRepr,
128{
129 #[inline(always)]
130 fn from_felt_repr(reader: &mut FeltReader<'_>) -> Self {
131 match reader.read().as_u64() {
132 0 => None,
133 1 => Some(T::from_felt_repr(reader)),
134 _ => panic!("Option: invalid tag"),
135 }
136 }
137}
138
139impl<T> FromFeltRepr for Vec<T>
143where
144 T: FromFeltRepr,
145{
146 #[inline(always)]
147 fn from_felt_repr(reader: &mut FeltReader<'_>) -> Self {
148 let len = reader.read().as_u64();
149 assert!(len <= u32::MAX as u64, "Vec: length out of range");
150 let len = len as usize;
151
152 let mut result = Vec::with_capacity(len);
153
154 let mut i = 0usize;
155 while i < len {
156 result.push(T::from_felt_repr(reader));
157 i += 1;
158 }
159 result
160 }
161}
162
163pub trait ToFeltRepr {
165 fn write_felt_repr(&self, writer: &mut FeltWriter<'_>);
167
168 fn to_felt_repr(&self) -> Vec<Felt> {
170 let mut data = Vec::with_capacity(256);
172 self.write_felt_repr(&mut FeltWriter::new(&mut data));
173 data
174 }
175}
176
177impl ToFeltRepr for Felt {
178 #[inline(always)]
179 fn write_felt_repr(&self, writer: &mut FeltWriter<'_>) {
180 writer.write(*self);
181 }
182}
183
184#[cfg(not(target_family = "wasm"))]
185impl ToFeltRepr for miden_core::Felt {
186 #[inline(always)]
187 fn write_felt_repr(&self, writer: &mut FeltWriter<'_>) {
188 writer.write((*self).into());
189 }
190}
191
192impl ToFeltRepr for u64 {
193 #[inline(always)]
194 fn write_felt_repr(&self, writer: &mut FeltWriter<'_>) {
195 let lo = (*self & 0xffff_ffff) as u32;
196 let hi = (*self >> 32) as u32;
197 writer.write(Felt::from_u32(lo));
198 writer.write(Felt::from_u32(hi));
199 }
200}
201
202impl ToFeltRepr for u32 {
203 #[inline(always)]
204 fn write_felt_repr(&self, writer: &mut FeltWriter<'_>) {
205 writer.write(Felt::from_u64_unchecked(*self as u64));
206 }
207}
208
209impl ToFeltRepr for u8 {
210 #[inline(always)]
211 fn write_felt_repr(&self, writer: &mut FeltWriter<'_>) {
212 writer.write(Felt::from_u64_unchecked(*self as u64));
213 }
214}
215
216impl ToFeltRepr for bool {
217 #[inline(always)]
218 fn write_felt_repr(&self, writer: &mut FeltWriter<'_>) {
219 writer.write(Felt::from_u64_unchecked(*self as u64));
220 }
221}
222
223impl<T> ToFeltRepr for Option<T>
229where
230 T: ToFeltRepr,
231{
232 #[inline(always)]
233 fn write_felt_repr(&self, writer: &mut FeltWriter<'_>) {
234 match self {
235 None => writer.write(Felt::from_u64_unchecked(0)),
236 Some(value) => {
237 writer.write(Felt::from_u64_unchecked(1));
238 value.write_felt_repr(writer);
239 }
240 }
241 }
242}
243
244impl<T> ToFeltRepr for Vec<T>
248where
249 T: ToFeltRepr,
250{
251 #[inline(always)]
252 fn write_felt_repr(&self, writer: &mut FeltWriter<'_>) {
253 let len = self.len();
254 assert!(len <= u32::MAX as usize, "Vec: length out of range");
255 writer.write(Felt::from_u64_unchecked(len as u64));
256
257 let mut i = 0usize;
258 while i < len {
259 self[i].write_felt_repr(writer);
260 i += 1;
261 }
262 }
263}