midenc_hir/ir/parse/
from_str_radix.rs1use crate::{Felt, Immediate};
2
3pub trait FromStrRadix: Sized {
4 type Error: core::error::Error;
5
6 fn try_from_str_radix(source: &str, radix: u32) -> Result<Self, Self::Error>;
7}
8
9macro_rules! from_str_radix_impl {
10 ($($t:ty),*) => {
11 $(
12 impl FromStrRadix for $t {
13 type Error = core::num::ParseIntError;
14
15 #[inline]
16 fn try_from_str_radix(source: &str, radix: u32) -> Result<Self, Self::Error> {
17 <$t>::from_str_radix(source, radix)
18 }
19 }
20 )*
21 }
22}
23
24from_str_radix_impl!(u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize);
25
26#[doc(hidden)]
27#[derive(Debug, thiserror::Error)]
28pub enum FeltOutOfRangeError {
29 #[error(transparent)]
30 Parse(#[from] core::num::ParseIntError),
31 #[error("invalid felt: {0} is larger than the field modulus")]
32 OutOfRange(u64),
33}
34
35impl FromStrRadix for Felt {
36 type Error = FeltOutOfRangeError;
37
38 fn try_from_str_radix(source: &str, radix: u32) -> Result<Self, Self::Error> {
39 let value = u64::try_from_str_radix(source, radix).map_err(FeltOutOfRangeError::Parse)?;
40 Felt::new(value).map_err(|err| FeltOutOfRangeError::OutOfRange(err.as_u64()))
41 }
42}
43
44impl FromStrRadix for Immediate {
45 type Error = core::num::ParseIntError;
46
47 fn try_from_str_radix(source: &str, radix: u32) -> Result<Self, Self::Error> {
48 if source.starts_with('-') {
49 let n = i128::try_from_str_radix(source, radix)?;
50 match n {
51 n if n > (i64::MAX as i128) || n < (i64::MIN as i128) => Ok(Immediate::I128(n)),
52 n if n > (i32::MAX as i128) || n < (i32::MIN as i128) => {
53 Ok(Immediate::I64(n as i64))
54 }
55 n if n > (i16::MAX as i128) || n < (i16::MIN as i128) => {
56 Ok(Immediate::I32(n as i32))
57 }
58 n if n > (i8::MAX as i128) || n < (i8::MIN as i128) => Ok(Immediate::I16(n as i16)),
59 n @ (0i128..=1i128) => Ok(Immediate::I8(n as i8)),
60 n => Ok(Immediate::I1(n == 1i128)),
61 }
62 } else {
63 let n = u128::try_from_str_radix(source, radix)?;
64 match n {
65 n if n > (u64::MAX as u128) => Ok(Immediate::U128(n)),
66 n if n > (u32::MAX as u128) => Ok(Immediate::U64(n as u64)),
67 n if n > (u16::MAX as u128) => Ok(Immediate::U32(n as u32)),
68 n if n > (u8::MAX as u128) => Ok(Immediate::U16(n as u16)),
69 n if n > 1u128 => Ok(Immediate::U8(n as u8)),
70 n => Ok(Immediate::I1(n == 1u128)),
71 }
72 }
73 }
74}