snarkvm_circuit_program/data/plaintext/
from_bits.rs1use super::*;
17
18impl<A: Aleo> FromBits for Plaintext<A> {
19 type Boolean = Boolean<A>;
20
21 fn from_bits_le(bits_le: &[Boolean<A>]) -> Self {
23 Self::from_bits_le_internal(bits_le, 0)
24 }
25
26 fn from_bits_be(bits_be: &[Boolean<A>]) -> Self {
28 Self::from_bits_be_internal(bits_be, 0)
29 }
30}
31
32impl<A: Aleo> Plaintext<A> {
33 fn from_bits_le_internal(bits_le: &[Boolean<A>], depth: usize) -> Self {
35 if depth > <A::Network as console::Network>::MAX_DATA_DEPTH {
37 A::halt(format!(
38 "Plaintext depth exceeds maximum limit: {}",
39 <A::Network as console::Network>::MAX_DATA_DEPTH
40 ))
41 }
42
43 let bits = bits_le;
44
45 let mut index = 0;
47
48 let mut next_bits = |n: usize| -> &[Boolean<A>] {
50 let subslice = bits.get(index..index + n);
52 if let Some(next_bits) = subslice {
54 index += n;
56 next_bits
58 } else {
59 A::halt("Insufficient bits.")
60 }
61 };
62
63 let mut variant = next_bits(2).iter().map(|b| b.eject_value());
64 let variant1 = variant.next().unwrap();
65 let variant2 = variant.next().unwrap();
66 let variant = [variant1, variant2];
67
68 if variant == [false, false] {
70 let literal_variant = U8::from_bits_le(next_bits(8));
71 let literal_size = U16::from_bits_le(next_bits(16)).eject_value();
72 let literal = Literal::from_bits_le(&literal_variant, next_bits(*literal_size as usize));
73
74 Self::Literal(literal, OnceCell::with_value(bits_le.to_vec()))
76 }
77 else if variant == [false, true] {
79 let num_members = U8::from_bits_le(next_bits(8)).eject_value();
80
81 let mut members = IndexMap::with_capacity(*num_members as usize);
82 for _ in 0..*num_members {
83 let identifier_size = U8::from_bits_le(next_bits(8)).eject_value();
84 let identifier = Identifier::from_bits_le(next_bits(*identifier_size as usize));
85
86 let member_size = U16::from_bits_le(next_bits(16)).eject_value();
87 let value = Plaintext::from_bits_le_internal(next_bits(*member_size as usize), depth + 1);
88
89 members.insert(identifier, value);
90 }
91
92 Self::Struct(members, OnceCell::with_value(bits_le.to_vec()))
94 }
95 else if variant == [true, false] {
97 let num_elements = U32::from_bits_le(next_bits(32)).eject_value();
98
99 let mut elements = Vec::with_capacity(*num_elements as usize);
100 for _ in 0..*num_elements {
101 let element_size = U16::from_bits_le(next_bits(16)).eject_value();
102 let value = Plaintext::from_bits_le_internal(next_bits(*element_size as usize), depth + 1);
103
104 elements.push(value);
105 }
106
107 Self::Array(elements, OnceCell::with_value(bits_le.to_vec()))
109 }
110 else {
112 A::halt("Unknown plaintext variant.")
113 }
114 }
115
116 fn from_bits_be_internal(bits_be: &[Boolean<A>], depth: usize) -> Self {
118 if depth > <A::Network as console::Network>::MAX_DATA_DEPTH {
120 A::halt(format!(
121 "Plaintext depth exceeds maximum limit: {}",
122 <A::Network as console::Network>::MAX_DATA_DEPTH
123 ))
124 }
125
126 let bits = bits_be;
127
128 let mut index = 0;
130
131 let mut next_bits = |n: usize| -> &[Boolean<A>] {
133 let subslice = bits.get(index..index + n);
135 if let Some(next_bits) = subslice {
137 index += n;
139 next_bits
141 } else {
142 A::halt("Insufficient bits.")
143 }
144 };
145
146 let mut variant = next_bits(2).iter().map(|b| b.eject_value());
147 let variant1 = variant.next().unwrap();
148 let variant2 = variant.next().unwrap();
149 let variant = [variant1, variant2];
150
151 if variant == [false, false] {
153 let literal_variant = U8::from_bits_be(next_bits(8));
154 let literal_size = U16::from_bits_be(next_bits(16)).eject_value();
155 let literal = Literal::from_bits_be(&literal_variant, next_bits(*literal_size as usize));
156
157 Self::Literal(literal, OnceCell::with_value(bits_be.to_vec()))
159 }
160 else if variant == [false, true] {
162 let num_members = U8::from_bits_be(next_bits(8)).eject_value();
163
164 let mut members = IndexMap::with_capacity(*num_members as usize);
165 for _ in 0..*num_members {
166 let identifier_size = U8::from_bits_be(next_bits(8)).eject_value();
167 let identifier = Identifier::from_bits_be(next_bits(*identifier_size as usize));
168
169 let member_size = U16::from_bits_be(next_bits(16)).eject_value();
170 let value = Plaintext::from_bits_be_internal(next_bits(*member_size as usize), depth + 1);
171
172 members.insert(identifier, value);
173 }
174
175 Self::Struct(members, OnceCell::with_value(bits_be.to_vec()))
177 }
178 else if variant == [true, false] {
180 let num_elements = U32::from_bits_be(next_bits(32)).eject_value();
181
182 let mut elements = Vec::with_capacity(*num_elements as usize);
183 for _ in 0..*num_elements {
184 let element_size = U16::from_bits_be(next_bits(16)).eject_value();
185 let value = Plaintext::from_bits_be_internal(next_bits(*element_size as usize), depth + 1);
186
187 elements.push(value);
188 }
189
190 Self::Array(elements, OnceCell::with_value(bits_be.to_vec()))
192 }
193 else {
195 A::halt("Unknown plaintext variant.")
196 }
197 }
198}