snarkvm_console_types_integers/
from_field.rs1use super::*;
17
18impl<E: Environment, I: IntegerType> FromField for Integer<E, I> {
19 type Field = Field<E>;
20
21 fn from_field(field: &Self::Field) -> Result<Self> {
27 debug_assert!(I::BITS < Field::<E>::size_in_bits() as u64);
31
32 let bits_le = field.to_bits_le();
34
35 let (bits_le, zero_bits) = bits_le.split_at(Self::size_in_bits());
37
38 ensure!(zero_bits.iter().all(|&bit| !bit), "Failed to convert field to integer: upper bits are not zero");
40
41 Self::from_bits_le(bits_le)
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use snarkvm_console_network_environment::Console;
50
51 type CurrentEnvironment = Console;
52
53 const ITERATIONS: u64 = 10_000;
54
55 fn check_from_field<I: IntegerType>() -> Result<()> {
56 let mut rng = TestRng::default();
57
58 for _ in 0..ITERATIONS {
59 let expected = Integer::<CurrentEnvironment, I>::rand(&mut rng);
61
62 let candidate = Integer::from_field(&expected.to_field()?)?;
64 assert_eq!(expected, candidate);
65
66 let expected = Field::<CurrentEnvironment>::rand(&mut rng);
68 let integer_max = match I::type_name() {
70 "u8" | "i8" => Field::<CurrentEnvironment>::from_u8(u8::MAX),
71 "u16" | "i16" => Field::<CurrentEnvironment>::from_u16(u16::MAX),
72 "u32" | "i32" => Field::<CurrentEnvironment>::from_u32(u32::MAX),
73 "u64" | "i64" => Field::<CurrentEnvironment>::from_u64(u64::MAX),
74 "u128" | "i128" => Field::<CurrentEnvironment>::from_u128(u128::MAX),
75 _ => panic!("Unsupported integer type."),
76 };
77 if expected > integer_max {
79 assert!(Integer::<_, I>::from_field(&expected).is_err());
81 } else {
82 assert!(Integer::<_, I>::from_field(&expected).is_ok());
84 }
85 }
86 Ok(())
87 }
88
89 #[test]
90 fn test_u8_from_field() -> Result<()> {
91 type I = u8;
92 check_from_field::<I>()
93 }
94
95 #[test]
96 fn test_i8_from_field() -> Result<()> {
97 type I = i8;
98 check_from_field::<I>()
99 }
100
101 #[test]
102 fn test_u16_from_field() -> Result<()> {
103 type I = u16;
104 check_from_field::<I>()
105 }
106
107 #[test]
108 fn test_i16_from_field() -> Result<()> {
109 type I = i16;
110 check_from_field::<I>()
111 }
112
113 #[test]
114 fn test_u32_from_field() -> Result<()> {
115 type I = u32;
116 check_from_field::<I>()
117 }
118
119 #[test]
120 fn test_i32_from_field() -> Result<()> {
121 type I = i32;
122 check_from_field::<I>()
123 }
124
125 #[test]
126 fn test_u64_from_field() -> Result<()> {
127 type I = u64;
128 check_from_field::<I>()
129 }
130
131 #[test]
132 fn test_i64_from_field() -> Result<()> {
133 type I = i64;
134 check_from_field::<I>()
135 }
136
137 #[test]
138 fn test_u128_from_field() -> Result<()> {
139 type I = u128;
140 check_from_field::<I>()
141 }
142
143 #[test]
144 fn test_i128_from_field() -> Result<()> {
145 type I = i128;
146 check_from_field::<I>()
147 }
148}