1use jzon::{object::Object, JsonValue};
4
5use crate::{
6 bits::to_vec,
7 enc::Error,
8 error::{EncodeError, JerEncodeErrorKind},
9 types::{fields::Fields, variants},
10};
11
12pub struct Encoder {
13 stack: alloc::vec::Vec<&'static str>,
14 constructed_stack: alloc::vec::Vec<Object>,
15 root_value: Option<JsonValue>,
16}
17
18impl Default for Encoder {
19 fn default() -> Self {
20 Self::new()
21 }
22}
23
24impl Encoder {
25 pub fn new() -> Self {
26 Self {
27 stack: alloc::vec![],
28 constructed_stack: alloc::vec![],
29 root_value: None,
30 }
31 }
32
33 pub fn root_value(self) -> Result<JsonValue, EncodeError> {
34 Ok(self
35 .root_value
36 .ok_or(JerEncodeErrorKind::NoRootValueFound)?)
37 }
38
39 pub fn to_json(self) -> alloc::string::String {
40 self.root_value.map_or(<_>::default(), |v| v.dump())
41 }
42
43 fn update_root_or_constructed(&mut self, value: JsonValue) -> Result<(), EncodeError> {
44 match self.stack.pop() {
45 Some(id) => {
46 self.constructed_stack
47 .last_mut()
48 .ok_or_else(|| JerEncodeErrorKind::JsonEncoder {
49 msg: "Internal stack mismatch!".into(),
50 })?
51 .insert(id, value);
52 }
53 None => {
54 self.root_value = Some(value);
55 }
56 };
57 Ok(())
58 }
59}
60
61impl crate::Encoder for Encoder {
62 type Ok = ();
63
64 type Error = EncodeError;
65
66 fn encode_any(
67 &mut self,
68 t: crate::Tag,
69 value: &crate::types::Any,
70 ) -> Result<Self::Ok, Self::Error> {
71 self.encode_octet_string(t, <_>::default(), &value.contents)
72 }
73
74 fn encode_bool(&mut self, _: crate::Tag, value: bool) -> Result<Self::Ok, Self::Error> {
75 self.update_root_or_constructed(JsonValue::Boolean(value))
76 }
77
78 fn encode_bit_string(
79 &mut self,
80 _t: crate::Tag,
81 constraints: crate::types::Constraints,
82 value: &crate::types::BitStr,
83 ) -> Result<Self::Ok, Self::Error> {
84 let bytes = to_vec(value)
85 .iter()
86 .fold(alloc::string::String::new(), |mut acc, bit| {
87 acc.push_str(&alloc::format!("{bit:02X?}"));
88 acc
89 });
90 let json_value = if constraints
91 .size()
92 .map_or(false, |s| s.constraint.is_fixed())
93 {
94 JsonValue::String(bytes)
95 } else {
96 let mut value_map = JsonValue::new_object();
97 value_map
98 .insert("value", bytes)
99 .and(value_map.insert("length", JsonValue::Number(value.len().into())))
100 .map_err(|_| {
101 EncodeError::custom("Failed to create BitString object!", self.codec())
102 })?;
103 value_map
104 };
105 self.update_root_or_constructed(json_value)
106 }
107
108 fn encode_enumerated<E: crate::types::Enumerated>(
109 &mut self,
110 _: crate::Tag,
111 value: &E,
112 ) -> Result<Self::Ok, Self::Error> {
113 self.update_root_or_constructed(JsonValue::String(alloc::string::String::from(
114 value.identifier(),
115 )))
116 }
117
118 fn encode_object_identifier(
119 &mut self,
120 _t: crate::Tag,
121 value: &[u32],
122 ) -> Result<Self::Ok, Self::Error> {
123 self.update_root_or_constructed(JsonValue::String(
124 value
125 .iter()
126 .map(|arc| alloc::format!("{arc}"))
127 .collect::<alloc::vec::Vec<alloc::string::String>>()
128 .join("."),
129 ))
130 }
131
132 fn encode_integer(
133 &mut self,
134 _t: crate::Tag,
135 _c: crate::types::Constraints,
136 value: &num_bigint::BigInt,
137 ) -> Result<Self::Ok, Self::Error> {
138 let as_i64: i64 =
139 value
140 .try_into()
141 .map_err(|_| JerEncodeErrorKind::ExceedsSupportedIntSize {
142 value: value.clone(),
143 })?;
144 self.update_root_or_constructed(JsonValue::Number(as_i64.into()))
145 }
146
147 fn encode_null(&mut self, _: crate::Tag) -> Result<Self::Ok, Self::Error> {
148 self.update_root_or_constructed(JsonValue::Null)
149 }
150
151 fn encode_octet_string(
152 &mut self,
153 _t: crate::Tag,
154 _c: crate::types::Constraints,
155 value: &[u8],
156 ) -> Result<Self::Ok, Self::Error> {
157 self.update_root_or_constructed(JsonValue::String(value.iter().fold(
158 alloc::string::String::new(),
159 |mut acc, bit| {
160 acc.push_str(&alloc::format!("{bit:02X?}"));
161 acc
162 },
163 )))
164 }
165
166 fn encode_general_string(
167 &mut self,
168 _t: crate::Tag,
169 _c: crate::types::Constraints,
170 value: &crate::types::GeneralString,
171 ) -> Result<Self::Ok, Self::Error> {
172 self.update_root_or_constructed(JsonValue::String(
173 alloc::string::String::from_utf8(value.to_vec())
174 .map_err(|e| JerEncodeErrorKind::InvalidCharacter { error: e })?,
175 ))
176 }
177
178 fn encode_utf8_string(
179 &mut self,
180 _t: crate::Tag,
181 _c: crate::types::Constraints,
182 value: &str,
183 ) -> Result<Self::Ok, Self::Error> {
184 self.update_root_or_constructed(JsonValue::String(value.into()))
185 }
186
187 fn encode_visible_string(
188 &mut self,
189 _t: crate::Tag,
190 _c: crate::types::Constraints,
191 value: &crate::types::VisibleString,
192 ) -> Result<Self::Ok, Self::Error> {
193 self.update_root_or_constructed(JsonValue::String(
194 alloc::string::String::from_utf8(value.as_iso646_bytes().to_vec())
195 .map_err(|e| JerEncodeErrorKind::InvalidCharacter { error: e })?,
196 ))
197 }
198
199 fn encode_ia5_string(
200 &mut self,
201 _t: crate::Tag,
202 _c: crate::types::Constraints,
203 value: &crate::types::Ia5String,
204 ) -> Result<Self::Ok, Self::Error> {
205 self.update_root_or_constructed(JsonValue::String(
206 alloc::string::String::from_utf8(value.as_iso646_bytes().to_vec())
207 .map_err(|e| JerEncodeErrorKind::InvalidCharacter { error: e })?,
208 ))
209 }
210
211 fn encode_printable_string(
212 &mut self,
213 _t: crate::Tag,
214 _c: crate::types::Constraints,
215 value: &crate::types::PrintableString,
216 ) -> Result<Self::Ok, Self::Error> {
217 self.update_root_or_constructed(JsonValue::String(
218 alloc::string::String::from_utf8(value.as_bytes().to_vec())
219 .map_err(|e| JerEncodeErrorKind::InvalidCharacter { error: e })?,
220 ))
221 }
222
223 fn encode_numeric_string(
224 &mut self,
225 _t: crate::Tag,
226 _c: crate::types::Constraints,
227 value: &crate::types::NumericString,
228 ) -> Result<Self::Ok, Self::Error> {
229 self.update_root_or_constructed(JsonValue::String(
230 alloc::string::String::from_utf8(value.as_bytes().to_vec())
231 .map_err(|e| JerEncodeErrorKind::InvalidCharacter { error: e })?,
232 ))
233 }
234
235 fn encode_teletex_string(
236 &mut self,
237 _t: crate::Tag,
238 _c: crate::types::Constraints,
239 _value: &crate::types::TeletexString,
240 ) -> Result<Self::Ok, Self::Error> {
241 todo!()
242 }
243
244 fn encode_bmp_string(
245 &mut self,
246 _t: crate::Tag,
247 _c: crate::types::Constraints,
248 value: &crate::types::BmpString,
249 ) -> Result<Self::Ok, Self::Error> {
250 self.update_root_or_constructed(JsonValue::String(
251 alloc::string::String::from_utf8(value.to_bytes())
252 .map_err(|e| JerEncodeErrorKind::InvalidCharacter { error: e })?,
253 ))
254 }
255
256 fn encode_generalized_time(
257 &mut self,
258 _t: crate::Tag,
259 value: &crate::types::GeneralizedTime,
260 ) -> Result<Self::Ok, Self::Error> {
261 self.update_root_or_constructed(JsonValue::String(
262 alloc::string::String::from_utf8(
263 crate::ber::enc::Encoder::datetime_to_canonical_generalized_time_bytes(value),
264 )
265 .map_err(|e| JerEncodeErrorKind::InvalidCharacter { error: e })?,
266 ))
267 }
268
269 fn encode_utc_time(
270 &mut self,
271 _t: crate::Tag,
272 value: &crate::types::UtcTime,
273 ) -> Result<Self::Ok, Self::Error> {
274 self.update_root_or_constructed(JsonValue::String(
275 alloc::string::String::from_utf8(
276 crate::ber::enc::Encoder::datetime_to_canonical_utc_time_bytes(value),
277 )
278 .map_err(|e| JerEncodeErrorKind::InvalidCharacter { error: e })?,
279 ))
280 }
281
282 fn encode_explicit_prefix<V: crate::Encode>(
283 &mut self,
284 _: crate::Tag,
285 value: &V,
286 ) -> Result<Self::Ok, Self::Error> {
287 value.encode(self)
288 }
289
290 fn encode_sequence<C, F>(
291 &mut self,
292 __t: crate::Tag,
293 encoder_scope: F,
294 ) -> Result<Self::Ok, Self::Error>
295 where
296 C: crate::types::Constructed,
297 F: FnOnce(&mut Self) -> Result<(), Self::Error>,
298 {
299 let mut field_names = [C::FIELDS, C::EXTENDED_FIELDS.unwrap_or(Fields::empty())]
300 .iter()
301 .flat_map(|f| f.iter())
302 .map(|f| f.name)
303 .collect::<alloc::vec::Vec<&str>>();
304 field_names.reverse();
305 for name in field_names {
306 self.stack.push(name);
307 }
308 self.constructed_stack.push(Object::new());
309 (encoder_scope)(self)?;
310 let value_map =
311 self.constructed_stack
312 .pop()
313 .ok_or_else(|| JerEncodeErrorKind::JsonEncoder {
314 msg: "Internal stack mismatch!".into(),
315 })?;
316 self.update_root_or_constructed(JsonValue::Object(value_map))
317 }
318
319 fn encode_sequence_of<E: crate::Encode>(
320 &mut self,
321 _t: crate::Tag,
322 value: &[E],
323 _c: crate::types::Constraints,
324 ) -> Result<Self::Ok, Self::Error> {
325 self.update_root_or_constructed(JsonValue::Array(value.iter().try_fold(
326 alloc::vec![],
327 |mut acc, v| {
328 let mut item_encoder = Self::new();
329 v.encode(&mut item_encoder).and(
330 item_encoder
331 .root_value()
332 .map(|rv| acc.push(rv))
333 .map(|_| acc),
334 )
335 },
336 )?))
337 }
338
339 fn encode_set<C, F>(&mut self, tag: crate::Tag, value: F) -> Result<Self::Ok, Self::Error>
340 where
341 C: crate::types::Constructed,
342 F: FnOnce(&mut Self) -> Result<(), Self::Error>,
343 {
344 self.encode_sequence::<C, F>(tag, value)
345 }
346
347 fn encode_set_of<E: crate::Encode>(
348 &mut self,
349 _t: crate::Tag,
350 value: &crate::types::SetOf<E>,
351 _c: crate::types::Constraints,
352 ) -> Result<Self::Ok, Self::Error> {
353 self.update_root_or_constructed(JsonValue::Array(value.iter().try_fold(
354 alloc::vec![],
355 |mut acc, v| {
356 let mut item_encoder = Self::new();
357 v.encode(&mut item_encoder).and(
358 item_encoder
359 .root_value()
360 .map(|rv| acc.push(rv))
361 .map(|_| acc),
362 )
363 },
364 )?))
365 }
366
367 fn encode_some<E: crate::Encode>(&mut self, value: &E) -> Result<Self::Ok, Self::Error> {
368 value.encode(self)
369 }
370
371 fn encode_some_with_tag_and_constraints<E: crate::Encode>(
372 &mut self,
373 _t: crate::Tag,
374 _c: crate::types::Constraints,
375 value: &E,
376 ) -> Result<Self::Ok, Self::Error> {
377 value.encode(self)
378 }
379
380 fn encode_none<E: crate::Encode>(&mut self) -> Result<Self::Ok, Self::Error> {
381 self.stack.pop();
382 Ok(())
383 }
384
385 fn encode_none_with_tag(&mut self, _t: crate::Tag) -> Result<Self::Ok, Self::Error> {
386 self.stack.pop();
387 Ok(())
388 }
389
390 fn encode_choice<E: crate::Encode + crate::types::Choice>(
391 &mut self,
392 _c: crate::types::Constraints,
393 tag: crate::types::Tag,
394 encode_fn: impl FnOnce(&mut Self) -> Result<crate::Tag, Self::Error>,
395 ) -> Result<Self::Ok, Self::Error> {
396 let variants = variants::Variants::from_slice(
397 &[E::VARIANTS, E::EXTENDED_VARIANTS.unwrap_or(&[])].concat(),
398 );
399
400 let identifier = variants
401 .iter()
402 .enumerate()
403 .find_map(|(i, &variant_tag)| {
404 (tag == variant_tag)
405 .then_some(E::IDENTIFIERS.get(i))
406 .flatten()
407 })
408 .ok_or_else(|| crate::error::EncodeError::variant_not_in_choice(self.codec()))?;
409
410 if variants.is_empty() {
411 self.update_root_or_constructed(JsonValue::Object(Object::new()))
412 } else {
413 self.constructed_stack.push(Object::new());
414 self.stack.push(identifier);
415 (encode_fn)(self)?;
416 let value_map =
417 self.constructed_stack
418 .pop()
419 .ok_or_else(|| JerEncodeErrorKind::JsonEncoder {
420 msg: "Internal stack mismatch!".into(),
421 })?;
422 self.update_root_or_constructed(JsonValue::Object(value_map))
423 }
424 }
425
426 fn encode_extension_addition<E: crate::Encode>(
427 &mut self,
428 _t: crate::Tag,
429 _c: crate::types::Constraints,
430 value: E,
431 ) -> Result<Self::Ok, Self::Error> {
432 value.encode(self)
433 }
434
435 fn encode_extension_addition_group<E>(
436 &mut self,
437 value: Option<&E>,
438 ) -> Result<Self::Ok, Self::Error>
439 where
440 E: crate::Encode + crate::types::Constructed,
441 {
442 match value {
443 Some(v) => v.encode(self),
444 None => self.encode_none::<E>(),
445 }
446 }
447
448 fn codec(&self) -> crate::Codec {
449 crate::Codec::Jer
450 }
451}