diff --git a/crates/stark-felt/Cargo.toml b/crates/stark-felt/Cargo.toml index b9dbf30..d2968dc 100644 --- a/crates/stark-felt/Cargo.toml +++ b/crates/stark-felt/Cargo.toml @@ -15,6 +15,7 @@ bitvec = { version = "1.0.1", default-features = false } serde = { version = "1.0.163", optional = true, default-features = false } lambdaworks-math = { version = "0.2.0", default_features = false } arbitrary = { version = "1.3.0", optional = true, default-features = false } +num-traits = { version = "0.2.16", default-features = false } [features] default = ["std", "serde"] diff --git a/crates/stark-felt/src/lib.rs b/crates/stark-felt/src/lib.rs index cba1536..e489cf3 100644 --- a/crates/stark-felt/src/lib.rs +++ b/crates/stark-felt/src/lib.rs @@ -3,6 +3,7 @@ use core::ops::{Add, Neg}; use bitvec::array::BitArray; +use num_traits::FromPrimitive; #[cfg(test)] mod arbitrary_proptest; @@ -307,68 +308,62 @@ impl TryFrom<&Felt> for NonZeroFelt { } } -impl From for Felt { - fn from(value: usize) -> Self { - Self::from(value as u64) +impl FromPrimitive for Felt { + fn from_i64(value: i64) -> Option { + Self::from_i128(value as i128) } -} -impl From for Felt { - fn from(value: u8) -> Self { - Self::from(value as u64) + fn from_u64(value: u64) -> Option { + Self::from_u128(value as u128) } -} - -impl From for Felt { - fn from(value: u32) -> Self { - Self::from(value as u64) - } -} -impl From for Felt { - fn from(value: u64) -> Self { - Self(FieldElement::from(value)) - } -} - -impl From for Felt { - fn from(value: u128) -> Self { - Self(FieldElement::from(&UnsignedInteger::from(value))) + fn from_i128(value: i128) -> Option { + let mut res = Self(FieldElement::from(&UnsignedInteger::from(value.unsigned_abs()))); + if value.is_negative() { + res = -res; + } + Some(res) } -} -impl From for Felt { - fn from(value: i32) -> Self { - Self::from(value as i64) + fn from_u128(value: u128) -> Option { + Some(Self(FieldElement::from(&UnsignedInteger::from(value)))) } } -impl From for Felt { - fn from(value: i64) -> Self { - if value.is_negative() { - Self::ZERO - - Self(FieldElement::from(&UnsignedInteger::from( - value.unsigned_abs(), - ))) - } else { - Self(FieldElement::from(&UnsignedInteger::from(value as u64))) +macro_rules! impl_from_u128 { + ($type:ty) => { + impl From<$type> for Felt { + fn from(value: $type) -> Self { + Self::from_u128(value as u128).expect("conversion from primitive is infallible") + } } } } -impl From for Felt { - fn from(value: i128) -> Self { - if value.is_negative() { - Self::ZERO - - Self(FieldElement::from(&UnsignedInteger::from( - value.unsigned_abs(), - ))) - } else { - Self(FieldElement::from(&UnsignedInteger::from(value as u128))) +impl_from_u128!(u8); +impl_from_u128!(u16); +impl_from_u128!(u32); +impl_from_u128!(u64); +impl_from_u128!(u128); +impl_from_u128!(usize); + +macro_rules! impl_from_i128 { + ($type:ty) => { + impl From<$type> for Felt { + fn from(value: $type) -> Self { + Self::from_i128(value as i128).expect("conversion from primitive is infallible") + } } } } +impl_from_i128!(i8); +impl_from_i128!(i16); +impl_from_i128!(i32); +impl_from_i128!(i64); +impl_from_i128!(i128); +impl_from_i128!(isize); + impl Add<&Felt> for u64 { type Output = Option;