Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_jdat/tests/string.rs

83.5 KiB, 52 runs

created by r1870400018:505, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use oxedyne_fe2o3_jdat::{
2 prelude::*,
3 tup2dat,
4 tup3dat,
5 tup4dat,
6 tup5dat,
7 tup6dat,
8 tup7dat,
9 tup8dat,
10 tup9dat,
11 tup10dat,
12 test_string_encode_decode_homogenous_tuple,
13 note::NoteConfig,
14 string::{
15 dec::*,
16 enc::*,
17 },
18 usr::{
19 UsrKinds,
20 UsrKindId,
21 },
22};
23
24use oxedyne_fe2o3_core::{
25 prelude::*,
26 test::test_it,
27};
28use oxedyne_fe2o3_num::prelude::*;
29use oxedyne_fe2o3_text::string::Stringer;
30
31use std::collections::BTreeMap;
32
33
34pub fn test_string_encdec_func(filter: &'static str) -> Outcome<()> {
35
36 res!(test_it(filter, &["String omnibus", "all", "omnibus"], || {
37 let kind_scopes = [
38 KindScope::Everything,
39 KindScope::Nothing,
40 KindScope::Most,
41 ];
42 let type_lower_cases = [true, false];
43 let byte_encodings = [
44 ByteEncoding::Base2x,
45 ByteEncoding::Binary,
46 ByteEncoding::Decimal,
47 ByteEncoding::Hex,
48 ByteEncoding::Octal,
49 ];
50 let int_encodings = [
51 IntEncoding::Binary,
52 IntEncoding::Decimal,
53 IntEncoding::Hex,
54 IntEncoding::Octal,
55 ];
56 let trailing_commas_opts = [true, false];
57 let hide_usr_types_opts = [true, false];
58
59 let ukind = UsrKindId::new(5, Some("my_type"), Some(Kind::U8));
60 let mut ukinds = UsrKinds::new(BTreeMap::new(), BTreeMap::new());
61 res!(ukinds.add(ukind.clone()));
62
63 // Vec of tuples to be encoded then decoded with various codec settings, and the kind
64 // expected from decoding with encoding KindScope::Nothing (as in JSON).
65 let dats: Vec<(Dat, Kind)> = vec![
66 // to encode json decode
67 (dat!(()), Kind::Str), // 1
68 (dat!(true), Kind::True), // 2
69 (dat!(false), Kind::False), // 3
70 (dat!(None::<u8>), Kind::Str), // 4
71 (dat!(0u8), Kind::U8), // 5
72 (dat!(0u16), Kind::U8), // 6
73 (dat!(0u32), Kind::U8), // 7
74 (dat!(0u64), Kind::U8), // 8
75 (dat!(0u128), Kind::U8), // 9
76 (dat!(0i8), Kind::U8), // 10
77 (dat!(0i16), Kind::U8), // 11
78 (dat!(0i32), Kind::U8), // 12
79 (dat!(0i64), Kind::U8), // 13
80 (dat!(0i128), Kind::U8), // 14
81 (dat!(u8::MAX), Kind::U8), // 15
82 (dat!(u16::MAX), Kind::U16), // 16
83 (dat!(u32::MAX), Kind::U32), // 17
84 (dat!(u64::MAX), Kind::U64), // 18
85 (dat!(u128::MAX), Kind::U128), // 19
86 (dat!(i8::MIN), Kind::I8), // 20
87 (dat!(i16::MIN), Kind::I16), // 21
88 (dat!(i32::MIN), Kind::I32), // 22
89 (dat!(i64::MIN), Kind::I64), // 23
90 (dat!(i128::MIN), Kind::I128), // 24
91 (dat!(i8::MAX), Kind::U8), // 25
92 (dat!(i16::MAX), Kind::U16), // 26
93 (dat!(i32::MAX), Kind::U32), // 27
94 (dat!(i64::MAX), Kind::U64), // 28
95 (dat!(i128::MAX), Kind::U128), // 29
96 (dat!(0.0f32), Kind::Adec), // 30
97 (dat!(f32::MIN), Kind::Adec), // 31
98 (dat!(f32::MAX), Kind::Adec), // 32
99 (dat!(0.0f64), Kind::Adec), // 33
100 (dat!(f64::MIN), Kind::Adec), // 34
101 (dat!(f64::MAX), Kind::Adec), // 35
102 (dat!(res!(aint!(fmt!("{}0", u128::MAX)))), Kind::Aint), // 36
103 (dat!(res!(aint!(fmt!("{}0", u128::MIN)))), Kind::U8), // 37
104 (dat!(res!(adec!(fmt!("{:e}0", f64::MAX)))), Kind::Adec), // 38
105 (dat!(res!(adec!(fmt!("{:e}0", f64::MIN)))), Kind::Adec), // 39
106 (Dat::C64(u32::MAX as u64), Kind::U32), // 40
107 (dat!("hello"), Kind::Str), // 41
108 (res!(Dat::try_from((ukind.clone(), Some(best_dat!(42))))), Kind::U8), // 42
109 (dat!(Box::new(best_dat!(-42))), Kind::I8), // 43
110 (dat!(Some(best_dat!(-256))), Kind::I16), // 44
111 //(dat!("# comment"), Kind::ABox), // 45
112 ];
113 let mut count: usize = 1;
114 let total = dats.len()
115 * kind_scopes.len()
116 * type_lower_cases.len()
117 * byte_encodings.len()
118 * int_encodings.len()
119 * trailing_commas_opts.len()
120 * hide_usr_types_opts.len();
121 let mut enc_cfg: EncoderConfig<_, _>;
122 let mut dec_cfg: DecoderConfig<_, _>;
123
124 for (i, (d1, k2)) in dats.iter().enumerate() {
125 test!("String encode and decode {:?}", d1);
126 for kind_scope in &kind_scopes {
127 for type_lower_case in &type_lower_cases {
128 for byte_encoding in &byte_encodings {
129 for int_encoding in &int_encodings {
130 for trailing_commas in &trailing_commas_opts {
131 for hide_usr_types in &hide_usr_types_opts {
132 enc_cfg = EncoderConfig::default();
133 enc_cfg.kind_scope = kind_scope.clone();
134 enc_cfg.type_lower_case = *type_lower_case;
135 enc_cfg.byte_encoding = byte_encoding.clone();
136 enc_cfg.int_encoding = int_encoding.clone();
137 enc_cfg.trailing_commas = *trailing_commas;
138 enc_cfg.hide_usr_types = *hide_usr_types;
139 enc_cfg.ukinds_opt = Some(ukinds.clone());
140 dec_cfg = DecoderConfig::default();
141 dec_cfg.trailing_comma_allowed = *trailing_commas;
142 dec_cfg.ukinds_opt = Some(ukinds.clone());
143
144 let d1_str = res!(d1.encode_string_with_config(&enc_cfg));
145 let d2 = res!(Dat::decode_string_with_config(&d1_str, &dec_cfg));
146 // If we decoded JSON, just be happy that there was no error.
147 // But if it's partly or entirely JDAT, check that in and out
148 // match.
149 if *kind_scope == KindScope::Nothing ||
150 (d1.kind().is_usr() && *hide_usr_types)
151 {
152 if d2.kind() != *k2 {
153 return Err(err!(
154 "Omnibus test {} of {} using dat #{}: The daticle {:?} was \
155 encoded to '{}' then decoded to {:?} using {:?} and {:?}, \
156 but since the type scope is {:?}, {:?} was expected.",
157 count, total, i+1, d1, d1_str, d2,
158 enc_cfg, dec_cfg, kind_scope, k2; Test, Mismatch));
159 }
160 } else {
161 if *d1 != d2 {
162 return Err(err!(
163 "Omnibus test {} of {} using dat #{}: The daticle {:?} was \
164 encoded to '{}' then decoded to {:?} (kind: {:?}) using {:?} \
165 and {:?}.",
166 count, total, i+1, d1, d1_str,
167 d2, d2.kind(), enc_cfg, dec_cfg; Test, Mismatch));
168 }
169 }
170 //test!("Omnibus test {} of {} successfully completed.", count, total);
171 count += 1;
172 }
173 }
174 }
175 }
176 }
177 }
178 }
179 test!("{} tests run", count - 1);
180 Ok(())
181 }));
182
183 res!(test_it(filter, &["Multiline string encoding 010", "all", "list", "map"], || {
184 let d = listdat![
185 1,
186 "two",
187 omapdat!{
188 3 => listdat![
189 4,
190 "five",
191 6,
192 ],
193 },
194 listdat![7,8,9],
195 ];
196 let expected = vec![
197 "[",
198 " 1,",
199 " \"two\",",
200 " {",
201 " 3: [",
202 " 4,",
203 " \"five\",",
204 " 6",
205 " ]",
206 " },",
207 " [",
208 " 7,",
209 " 8,",
210 " 9",
211 " ]",
212 "]",
213 ];
214 test!("{}", d);
215 let json = res!(d.json_to_lines(" "));
216 let lines: Vec<&str> = json.lines().collect();
217 test!("Display output:");
218 for (i, line) in lines.iter().enumerate() {
219 test!("{:03}: {}", i + 1, line);
220 }
221 test!("Expected output:");
222 for (i, line) in expected.iter().enumerate() {
223 test!("{:03}: {}", i + 1, line);
224 }
225 req!(lines.len(), expected.len());
226 let mut c = 0;
227 for line in lines {
228 req!(line, expected[c].to_string(), "(L: actual, R: expected), line {}", c + 1);
229 c += 1;
230 }
231 Ok(())
232 }));
233
234 res!(test_it(filter, &["Multiline string encoding 013", "all", "map"], || {
235 let d = mapdat!{
236 1 => 2,
237 3 => mapdat!{
238 4 => 5,
239 6 => mapdat!{
240 7 => 8,
241 9 => 10,
242 },
243 11 => 12,
244 },
245 13 => 14,
246 };
247 let expected = vec![
248 "{",
249 " 1: 2,",
250 " 3: {",
251 " 4: 5,",
252 " 6: {",
253 " 7: 8,",
254 " 9: 10",
255 " },",
256 " 11: 12",
257 " },",
258 " 13: 14",
259 "}",
260 ];
261 test!("{}", d);
262 let json = res!(d.json_to_lines(" "));
263 let lines: Vec<&str> = json.lines().collect();
264 test!("Display output:");
265 for line in &lines {
266 test!("{}", line);
267 }
268 test!("Expected output:");
269 for line in &expected {
270 test!("{}", line);
271 }
272 req!(lines.len(), expected.len());
273 let mut c = 0;
274 for line in lines {
275 req!(line, expected[c].to_string(), "(L: actual, R: expected), line {}", c + 1);
276 c += 1;
277 }
278 Ok(())
279 }));
280
281 res!(test_it(filter, &["Multiline string encoding 020", "all", "list"], || {
282 let d = dat!(listdat![
283 1,
284 "two",
285 omapdat!{
286 3 => listdat![
287 4,
288 "five",
289 6,
290 ],
291 },
292 listdat![7,8,9],
293 ]);
294 let expected = vec![
295 "(list|[",
296 " (i32|1),",
297 " (str|\"two\"),",
298 " (omap|{",
299 " (i32|3): (list|[",
300 " (i32|4),",
301 " (str|\"five\"),",
302 " (i32|6),",
303 " ]),",
304 " }),",
305 " (list|[",
306 " (i32|7),",
307 " (i32|8),",
308 " (i32|9),",
309 " ]),",
310 "])",
311 ];
312 test!("{:?}", d);
313 let lines = d.to_lines(" ", true);
314 test!("Debug output:");
315 for line in &lines {
316 test!("{}", line);
317 }
318 test!("Expected output:");
319 for line in &expected {
320 test!("{}", line);
321 }
322 req!(lines.len(), expected.len());
323 let mut c = 0;
324 for line in lines {
325 req!(line, expected[c].to_string().to_lowercase());
326 c += 1;
327 }
328 Ok(())
329 }));
330
331 res!(test_it(filter, &["String decoding 000", "all", "str"], || {
332 test!("bring it");
333 let d = res!(Dat::decode_string("(STR|\"\")"));
334 test!("{:?}", d);
335 let expected = Dat::Str("".to_string());
336 req!(d, expected);
337 Ok(())
338 }));
339
340 res!(test_it(filter, &["String decoding 010", "all", "str"], || {
341 // Preserve quoted spaces.
342 let d = res!(Dat::decode_string("\" hello \""));
343 let expected = dat!(" hello ");
344 req!(d, expected);
345 Ok(())
346 }));
347
348 res!(test_it(filter, &["String decoding 020", "all", "str"], || {
349 // If unquoted, with no () brackets, interpret as a string.
350 let d = res!(Dat::decode_string("hello"));
351 let expected = dat!("hello");
352 req!(d, expected);
353 Ok(())
354 }));
355
356 res!(test_it(filter, &["String decoding 030", "all", "str"], || {
357 // Quote protection
358 let d = res!(Dat::decode_string("he\"(]\"o"));
359 let expected = dat!("he(]o");
360 req!(d, expected);
361 Ok(())
362 }));
363
364 res!(test_it(filter, &["String decoding 040", "all", "str"], || {
365 let d = res!(Dat::decode_string("(STR|hello)"));
366 let expected = dat!("hello");
367 req!(d, expected);
368 Ok(())
369 }));
370
371 res!(test_it(filter, &["String decoding 050", "all", "str"], || {
372 let d = res!(Dat::decode_string("(STR|\"hello\")"));
373 let expected = dat!("hello");
374 req!(d, expected);
375 Ok(())
376 }));
377
378 res!(test_it(filter, &["String decoding 060", "all", "empty"], || {
379 let d = res!(Dat::decode_string("\"empty\"")); // quotes should protect strings
380 let expected = dat!("empty");
381 req!(d, expected);
382 Ok(())
383 }));
384
385 res!(test_it(filter, &["String decoding 070", "all", "empty"], || {
386 let d = res!(Dat::decode_string("(EMPTY)"));
387 let expected = dat!(());
388 req!(d, expected);
389 Ok(())
390 }));
391
392 res!(test_it(filter, &["String decoding 080", "all", "empty"], || {
393 match Dat::decode_string("(Empty|)") {
394 Ok(_) => return Err(err!(
395 "Decoder should have detected superfluous '|' char."; Test, Invalid)),
396 Err(e) => test!("Correctly detected error: {}", e),
397 };
398 Ok(())
399 }));
400
401 res!(test_it(filter, &["String decoding 090", "all", "empty"], || {
402 let d = res!(Dat::decode_string("()"));
403 let expected = dat!(());
404 req!(d, expected);
405 Ok(())
406 }));
407
408 res!(test_it(filter, &["String decoding 100", "all", "bool"], || {
409 let d = res!(Dat::decode_string("(TRUE)"));
410 let expected = dat!(true);
411 req!(d, expected);
412 Ok(())
413 }));
414
415 res!(test_it(filter, &["String decoding 110", "all", "bool"], || {
416 match Dat::decode_string("(true|)") {
417 Ok(_) => return Err(err!(
418 "Decoder should have detected superfluous '|' char."; Test, Invalid)),
419 Err(e) => test!("Correctly detected error: {}", e),
420 };
421 Ok(())
422 }));
423
424 res!(test_it(filter, &["String decoding 120", "all", "bool"], || {
425 let d = res!(Dat::decode_string("(FALSE)"));
426 let expected = dat!(false);
427 req!(d, expected);
428 Ok(())
429 }));
430
431 res!(test_it(filter, &["String decoding 130", "all", "bool"], || {
432 match Dat::decode_string("(\nfalse | )") {
433 Ok(_) => return Err(err!(
434 "Decoder should have detected superfluous '|' char."; Test, Invalid)),
435 Err(e) => test!("Correctly detected error: {}", e),
436 };
437 Ok(())
438 }));
439
440 res!(test_it(filter, &["String decoding 140", "all", "u16"], || {
441 let d = res!(Dat::decode_string("(U16|0)"));
442 let expected = Dat::U16(0);
443 req!(d, expected);
444 Ok(())
445 }));
446
447 res!(test_it(filter, &["String decoding 150", "all", "i64"], || {
448 let d = res!(Dat::decode_string("(I64|-4)"));
449 let expected = Dat::I64(-4);
450 req!(d, expected);
451 Ok(())
452 }));
453
454 res!(test_it(filter, &["String decoding 160", "all", "i16", "minsize"], || {
455 let d = res!(Dat::decode_string("-420"));
456 let expected = Dat::I16(-420);
457 req!(d, expected);
458 Ok(())
459 }));
460
461 res!(test_it(filter, &["String decoding 170", "all", "u8"], || {
462 let d = res!(Dat::decode_string("(U8|42)"));
463 let expected = dat!(42u8);
464 req!(d, expected);
465 Ok(())
466 }));
467
468 res!(test_it(filter, &["String decoding 180", "all", "adec"], || {
469 let d = res!(Dat::decode_string("42.1234"));
470 let expected = dat!(res!(adec!(42.1234)));
471 req!(d, expected);
472 Ok(())
473 }));
474
475 res!(test_it(filter, &["String decoding 190", "all", "adec"], || {
476 let d = res!(Dat::decode_string("-42.1234"));
477 let expected = dat!(res!(adec!("-42.1234")));
478 req!(d, expected);
479 Ok(())
480 }));
481
482 res!(test_it(filter, &["String decoding 200", "all", "u8", "hex"], || {
483 let d = res!(Dat::decode_string("0xec"));
484 let expected = Dat::U8(236);
485 req!(d, expected);
486 Ok(())
487 }));
488
489 res!(test_it(filter, &["String decoding 210", "all", "u8", "hex"], || {
490 let jdat_enc = EncoderConfig::<(), ()>::jdat(None);
491 let jdat_dec = DecoderConfig::<(), ()>::jdat(None);
492 let d1 = Dat::U8(0xf0u8);
493 let d1_str = res!(d1.encode_string_with_config(&jdat_enc));
494 test!("jdat = {}", d1_str);
495 let d2 = res!(Dat::decode_string_with_config(d1_str.clone(), &jdat_dec));
496 req!(d1, d2);
497 Ok(())
498 }));
499
500 res!(test_it(filter, &["String decoding 215", "all", "b16", "base64"], || {
501 let jdat_enc = EncoderConfig::<(), ()>::jdat(None);
502 let jdat_dec = DecoderConfig::<(), ()>::jdat(None);
503 let d1 = Dat::B16((u128::MAX/13).to_be_bytes());
504 let d1_str = res!(d1.encode_string_with_config(&jdat_enc));
505 test!("jdat = {}", d1_str);
506 let d2 = res!(Dat::decode_string_with_config(d1_str.clone(), &jdat_dec));
507 req!(d1, d2);
508 Ok(())
509 }));
510
511 res!(test_it(filter, &["String decoding 220", "all", "u8", "minsize"], || {
512 let d = res!(Dat::decode_string("\"42\""));
513 let expected = dat!("42");
514 req!(d, expected);
515 Ok(())
516 }));
517
518 res!(test_it(filter, &["String decoding 230", "all", "u8", "str"], || {
519 match Dat::decode_string("(U8|\"42\")") {
520 Ok(d) => return Err(err!(
521 "String decoding should have rejected the attempt to \
522 coerce a string to {:?}.", d; Test, Invalid)),
523 Err(e) => test!("Correctly detected error: {}", e),
524 }
525 Ok(())
526 }));
527
528 res!(test_it(filter, &["String decoding 240", "all", "c64"], || {
529 let d = res!(Dat::decode_string("(C64|42)"));
530 let expected = Dat::C64(42);
531 req!(d, expected);
532 Ok(())
533 }));
534
535 res!(test_it(filter, &["String decoding 300", "all", "list"], || {
536 let d = res!(Dat::decode_string("[1, 2, 3, 4]"));
537 let expected = listdat![1u8, 2u8, 3u8, 4u8];
538 req!(d, expected);
539 Ok(())
540 }));
541
542 res!(test_it(filter, &["String decoding 305", "all", "list"], || {
543 let d = res!(Dat::decode_string("[1, 2, 3, (empty), 4]"));
544 test!("{:?}", d);
545 let expected = listdat![1u8, 2u8, 3u8, (), 4u8];
546 req!(d, expected);
547 Ok(())
548 }));
549
550 res!(test_it(filter, &["String decoding 310", "all", "list"], || {
551 match Dat::decode_string("[1,2,3,4") {
552 Ok(_) => return Err(err!(
553 "String decoding should have detected incomplete list."; Test, Invalid)),
554 Err(e) => test!("Correctly detected error: {}", e),
555 };
556 Ok(())
557 }));
558
559 res!(test_it(filter, &["String decoding 320", "all", "list"], || {
560 match Dat::decode_string("1,2,3,4") {
561 Ok(_) => return Err(err!(
562 "String decoding should have detected incomplete list."; Test, Invalid)),
563 Err(e) => test!("Correctly detected error: {}", e),
564 };
565 Ok(())
566 }));
567
568 res!(test_it(filter, &["String decoding 330", "all", "list"], || {
569 match Dat::decode_string("1,2,3,4]") {
570 Ok(_) => return Err(err!(
571 "String decoding should have detected incomplete list."; Test, Invalid)),
572 Err(e) => test!("Correctly detected error: {}", e),
573 };
574 Ok(())
575 }));
576
577 res!(test_it(filter, &["String decoding 340", "all", "list"], || {
578 // nested list at begining
579 let d = res!(Dat::decode_string("[[1,2],3,-408]"));
580 let expected = listdat![listdat![1u8,2u8],3u8,-408i16];
581 req!(d, expected);
582 Ok(())
583 }));
584
585 res!(test_it(filter, &["String decoding 350", "all", "list"], || {
586 // nested list in middle
587 let d = res!(Dat::decode_string("[1,[2,3],408]"));
588 let expected = listdat![1u8,listdat![2u8,3u8],408u16];
589 req!(d, expected);
590 Ok(())
591 }));
592
593 res!(test_it(filter, &["String decoding 360", "all", "list"], || {
594 // nested list at end
595 let d = res!(Dat::decode_string("[1,2,[3,-4]]"));
596 let expected = listdat![1u8,2u8,listdat![3u8,-4i8]];
597 req!(d, expected);
598 Ok(())
599 }));
600
601 res!(test_it(filter, &["String decoding 370", "all", "list"], || {
602 // trailing comma
603 let d = res!(Dat::decode_string("[1,2,3,4,]"));
604 let expected = listdat![dat!(1u8),dat!(2u8),dat!(3u8),dat!(4u8)];
605 req!(d, expected);
606 Ok(())
607 }));
608
609 res!(test_it(filter, &["String decoding 380", "all", "list"], || {
610 // triple nesting
611 let d = res!(Dat::decode_string("[1,[2,[3,4]],5]"));
612 let expected = listdat![1u8,listdat![2u8,listdat![3u8,4u8]],5u8];
613 req!(d, expected);
614 Ok(())
615 }));
616
617 res!(test_it(filter, &["String decoding 390", "all", "list"], || {
618 let d = res!(Dat::decode_string("(LIST|[1,2,3,4])"));
619 let expected = listdat![1u8,2u8,3u8,4u8];
620 req!(d, expected);
621 Ok(())
622 }));
623
624 res!(test_it(filter, &["String decoding 400", "all", "list"], || {
625 let d = res!(Dat::decode_string("[(U8|1),(I32|2),(STR|3),(I64|-4)]"));
626 let expected = listdat![1u8,2i32,"3".to_string(),-4i64];
627 req!(d, expected);
628 Ok(())
629 }));
630
631 res!(test_it(filter, &["String decoding 410", "all", "list"], || {
632 let d = res!(Dat::decode_string("(LIST|[(U8|1),(I32|2),(STR|3),(I64|-4)])"));
633 let expected = listdat![1u8,2i32,"3".to_string(),-4i64];
634 req!(d, expected);
635 Ok(())
636 }));
637
638 res!(test_it(filter, &["String decoding 420", "all", "list"], || {
639 let d = res!(Dat::decode_string("[1,[2,(LIST|[(U16|3),4])],5]"));
640 let expected = listdat![1u8,listdat![2u8,listdat![3u16,4u8]],5u8];
641 req!(d, expected);
642 Ok(())
643 }));
644
645 res!(test_it(filter, &["String decoding 430", "all", "list"], || {
646 let d = res!(Dat::decode_string("[1,(FALSE)]"));
647 let expected = listdat![1u8,dat!(false)];
648 req!(d, expected);
649 Ok(())
650 }));
651
652 res!(test_it(filter, &["String decoding 440", "all", "list"], || {
653 let d = res!(Dat::decode_string("[(FALSE),1]"));
654 let expected = listdat![dat!(false),1u8];
655 req!(d, expected);
656 Ok(())
657 }));
658
659 res!(test_it(filter, &["String decoding 450", "all", "list"], || {
660 let d = res!(Dat::decode_string("[(),1]"));
661 let expected = listdat![dat!(()),1u8];
662 req!(d, expected);
663 Ok(())
664 }));
665
666 res!(test_it(filter, &["String decoding 460", "all", "list"], || {
667 let d = res!(Dat::decode_string("[(U8|42),1]"));
668 let expected = listdat![42u8,1u8];
669 req!(d, expected);
670 Ok(())
671 }));
672
673 res!(test_it(filter, &["String decoding 470", "all", "tuple"], || {
674 match Dat::decode_string("(T2|[1, ])") {
675 Ok(_) => return Err(err!(
676 "String decoding should have detected incorrect list length."; Test, Invalid)),
677 Err(e) => test!("Correctly detected error: {}", e),
678 }
679 let d = res!(Dat::decode_string("(T2|[1, 2])"));
680 let expected = tup2dat![1u8,2u8,];
681 req!(d, expected);
682 Ok(())
683 }));
684
685 res!(test_it(filter, &["String decoding 480", "all", "tuple"], || {
686 match Dat::decode_string("(T3|[1, 2, ])") {
687 Ok(_) => return Err(err!(
688 "String decoding should have detected incorrect list length."; Test, Invalid)),
689 Err(e) => test!("Correctly detected error: {}", e),
690 }
691 let d = res!(Dat::decode_string("(T3|[1, 2, 3])"));
692 let expected = tup3dat![1u8,2u8,3u8];
693 req!(d, expected);
694 Ok(())
695 }));
696
697 res!(test_it(filter, &["String decoding 490", "all", "tuple"], || {
698 match Dat::decode_string("(T4|[1, 2, ])") {
699 Ok(_) => return Err(err!(
700 "String decoding should have detected incorrect list length."; Test, Invalid)),
701 Err(e) => test!("Correctly detected error: {}", e),
702 }
703 let d = res!(Dat::decode_string("(T4|[1, 2, 3, 4])"));
704 let expected = tup4dat![1u8,2u8,3u8,4u8];
705 req!(d, expected);
706 Ok(())
707 }));
708
709 res!(test_it(filter, &["String decoding 500", "all", "tuple"], || {
710 match Dat::decode_string("(T5|[1, 2, ])") {
711 Ok(_) => return Err(err!(
712 "String decoding should have detected incorrect list length."; Test, Invalid)),
713 Err(e) => test!("Correctly detected error: {}", e),
714 }
715 let d = res!(Dat::decode_string("(T5|[1, 2, 3, 4, 5])"));
716 let expected = tup5dat![1u8,2u8,3u8,4u8,5u8];
717 req!(d, expected);
718 Ok(())
719 }));
720
721 res!(test_it(filter, &["String decoding 510", "all", "tuple"], || {
722 match Dat::decode_string("(T6|[1, 2, ])") {
723 Ok(_) => return Err(err!(
724 "String decoding should have detected incorrect list length."; Test, Invalid)),
725 Err(e) => test!("Correctly detected error: {}", e),
726 }
727 let d = res!(Dat::decode_string("(T6|[1, 2, 3, 4, 5, 6])"));
728 let expected = tup6dat![1u8,2u8,3u8,4u8,5u8,6u8];
729 req!(d, expected);
730 Ok(())
731 }));
732
733 res!(test_it(filter, &["String decoding 520", "all", "tuple"], || {
734 match Dat::decode_string("(T7|[1, 2, ])") {
735 Ok(_) => return Err(err!(
736 "String decoding should have detected incorrect list length."; Test, Invalid)),
737 Err(e) => test!("Correctly detected error: {}", e),
738 }
739 let d = res!(Dat::decode_string("(T7|[1, 2, 3, 4, 5, 6, 7])"));
740 let expected = tup7dat![1u8,2u8,3u8,4u8,5u8,6u8,7u8];
741 req!(d, expected);
742 Ok(())
743 }));
744
745 res!(test_it(filter, &["String decoding 530", "all", "tuple"], || {
746 match Dat::decode_string("(T8|[1, 2, ])") {
747 Ok(_) => return Err(err!(
748 "String decoding should have detected incorrect list length."; Test, Invalid)),
749 Err(e) => test!("Correctly detected error: {}", e),
750 }
751 let d = res!(Dat::decode_string("(T8|[1, 2, 3, 4, 5, 6, 7, 8])"));
752 let expected = tup8dat![1u8,2u8,3u8,4u8,5u8,6u8,7u8,8u8];
753 req!(d, expected);
754 Ok(())
755 }));
756
757 res!(test_it(filter, &["String decoding 540", "all", "tuple"], || {
758 match Dat::decode_string("(T9|[1, 2, ])") {
759 Ok(_) => return Err(err!(
760 "String decoding should have detected incorrect list length."; Test, Invalid)),
761 Err(e) => test!("Correctly detected error: {}", e),
762 }
763 let d = res!(Dat::decode_string("(T9|[1, 2, 3, 4, 5, 6, 7, 8, 9])"));
764 let expected = tup9dat![1u8,2u8,3u8,4u8,5u8,6u8,7u8,8u8,9u8];
765 req!(d, expected);
766 Ok(())
767 }));
768
769 res!(test_it(filter, &["String decoding 550", "all", "tuple"], || {
770 match Dat::decode_string("(T10|[1, 2, ])") {
771 Ok(_) => return Err(err!(
772 "String decoding should have detected incorrect list length."; Test, Invalid)),
773 Err(e) => test!("Correctly detected error: {}", e),
774 }
775 let d = res!(Dat::decode_string("(T10|[1, 2, 3, 4, 5, 6, 7, 8, 9, 10])"));
776 let expected = tup10dat![1u8,2u8,3u8,4u8,5u8,6u8,7u8,8u8,9u8,10u8];
777 req!(d, expected, "(L: actual, R: expected)");
778 Ok(())
779 }));
780
781 res!(test_it(filter, &["String decoding 560", "all", "list", "tuple"], || {
782 // combining default LIST with a fixed length list, nested in middle
783 let d = res!(Dat::decode_string("[1,(T2|[2,3]),4]"));
784 let expected = listdat![1u8,tup2dat![2u8,3u8],4u8];
785 req!(d, expected, "(L: actual, R: expected)");
786 Ok(())
787 }));
788
789 res!(test_it(filter, &["String decoding 562", "all", "list", "tuple"], || {
790 // Infer tuple without kindicle.
791 let d = res!(Dat::decode_string("(1,2,3)"));
792 let expected = tup3dat![ 1u8, 2u8, 3u8 ];
793 req!(d, expected, "(L: actual, R: expected)");
794 Ok(())
795 }));
796
797 res!(test_it(filter, &["String decoding 564", "all", "list", "tuple"], || {
798 // Infer tuple without kindicle.
799 let d = res!(Dat::decode_string("((u8|1),2,(i16|3))"));
800 let expected = tup3dat![ 1u8, 2u8, 3i16 ];
801 req!(d, expected, "(L: actual, R: expected)");
802 Ok(())
803 }));
804
805 res!(test_it(filter, &["String decoding 570", "all", "map"], || {
806 let d = res!(Dat::decode_string("{1:2,3:4,5:6}"));
807 let expected = mapdat!{
808 1u8 => 2u8,
809 3u8 => 4u8,
810 5u8 => 6u8,
811 };
812 req!(d, expected);
813 Ok(())
814 }));
815
816 res!(test_it(filter, &["String decoding 580", "all", "map"], || {
817 match Dat::decode_string("{1:2,3:4") {
818 Ok(_) => return Err(err!(
819 "String decoding should have detected incomplete map."; Test, Invalid)),
820 Err(e) => test!("Correctly detected error: {}", e),
821 };
822 Ok(())
823 }));
824
825 res!(test_it(filter, &["String decoding 590", "all", "map"], || {
826 match Dat::decode_string("1:2,3:4") {
827 Ok(_) => return Err(err!(
828 "String decoding should have detected incomplete map."; Test, Invalid)),
829 Err(e) => test!("Correctly detected error: {}", e),
830 };
831 Ok(())
832 }));
833
834 res!(test_it(filter, &["String decoding 600", "all", "map"], || {
835 match Dat::decode_string("1:2,3:4}") {
836 Ok(_) => return Err(err!(
837 "String decoding should have detected incomplete map."; Test, Invalid)),
838 Err(e) => test!("Correctly detected error: {}", e),
839 };
840 Ok(())
841 }));
842
843 res!(test_it(filter, &["String decoding 610", "all", "map"], || {
844 let d = res!(Dat::decode_string("(MAP|{1:2,3:4,5:6})"));
845 let expected = dat!(mapdat!{
846 1u8 => 2u8,
847 3u8 => 4u8,
848 5u8 => 6u8,
849 });
850 req!(d, expected);
851 Ok(())
852 }));
853
854 res!(test_it(filter, &["String decoding 620", "all", "map"], || {
855 // nested map at beginning key
856 let d = res!(Dat::decode_string("{{1:-2,3:-4}:5,6:7}"));
857 let expected = mapdat!{
858 mapdat!{
859 1u8 => -2i8,
860 3u8 => -4i8,
861 } => 5u8,
862 6u8 => 7u8,
863 };
864 req!(d, expected);
865 Ok(())
866 }));
867
868 res!(test_it(filter, &["String decoding 630", "all", "map"], || {
869 // nested map at beginning pair
870 let d = res!(Dat::decode_string("{{1:2,3:4}:{5:6,7:8},9:10}"));
871 let expected = mapdat!{
872 mapdat!{
873 1u8 => 2u8,
874 3u8 => 4u8,
875 } => mapdat!{
876 5u8 => 6u8,
877 7u8 => 8u8,
878 },
879 9u8 => 10u8,
880 };
881 req!(d, expected);
882 Ok(())
883 }));
884
885 res!(test_it(filter, &["String decoding 640", "all", "map"], || {
886 // triple nested map
887 let d = res!(Dat::decode_string("
888 {
889 {
890 1:{
891 2:3,
892 4:5,
893 },
894 5:6,
895 }:{
896 7:8,
897 9:10,
898 },
899 11:12,
900 }"));
901 let expected = mapdat!{
902 mapdat!{
903 1u8 => mapdat!{
904 2u8 => 3u8,
905 4u8 => 5u8,
906 },
907 5u8 => 6u8,
908 } => mapdat!{
909 7u8 => 8u8,
910 9u8 => 10u8,
911 },
912 11u8 => 12u8,
913 };
914 req!(d, expected);
915 Ok(())
916 }));
917
918 res!(test_it(filter, &["String decoding 644", "all", "mixed"], || {
919 let d = res!(Dat::decode_string("[1,{2:3,4:5},6]"));
920 let expected = listdat![
921 1u8,
922 mapdat!{
923 2u8 => 3u8,
924 4u8 => 5u8,
925 },
926 6u8,
927 ];
928 req!(d, expected);
929 Ok(())
930 }));
931
932 res!(test_it(filter, &["String decoding 645", "all", "mixed"], || {
933 let d = res!(Dat::decode_string("[{1:2,3:4}, (u64|1)]"));
934 let expected = listdat![
935 mapdat!{
936 1u8 => 2u8,
937 3u8 => 4u8,
938 },
939 1u64,
940 ];
941 req!(d, expected);
942 Ok(())
943 }));
944
945 res!(test_it(filter, &["String decoding 650", "all", "map"], || {
946 let d = res!(Dat::decode_string("{1:2,\"3\":\"4\",}"));
947 let expected = mapdat!{
948 1u8 => 2u8,
949 "3" => "4",
950 };
951 req!(d, expected);
952 Ok(())
953 }));
954
955 res!(test_it(filter, &["String decoding 660", "all", "map"], || {
956 let d = res!(Dat::decode_string("{1:[\"a\", \"b\"],}"));
957 let expected = mapdat!{
958 1u8 => listdat!["a", "b"],
959 };
960 req!(d, expected);
961 Ok(())
962 }));
963
964 res!(test_it(filter, &["String decoding 670", "all", "map"], || {
965 let d = res!(Dat::decode_string("{1:[2000, 3000]}"));
966 let expected = mapdat!{
967 1u8 => listdat![2000u16, 3000u16],
968 };
969 req!(d, expected);
970 Ok(())
971 }));
972
973 res!(test_it(filter, &["String decoding 680", "all", "map"], || {
974 let d = res!(Dat::decode_string("{1:{2:[3, 4]}}"));
975 let expected = mapdat!{
976 1u8 => mapdat!{
977 2u8 => listdat![3u8, 4u8],
978 },
979 };
980 req!(d, expected);
981 Ok(())
982 }));
983
984 res!(test_it(filter, &["String decoding 682", "all", "map"], || {
985 let d = res!(Dat::decode_string("(omap|{1:{2:[3, 4]}})"));
986 let expected = omapdat!{
987 1u8 => mapdat!{
988 2u8 => listdat![3u8, 4u8],
989 },
990 };
991 req!(d, expected);
992 Ok(())
993 }));
994
995 res!(test_it(filter, &["String decoding 684", "all", "map", "usr"], || {
996 // Provides a baseline for debugging "String decoding 685" test.
997 let mut uks = UsrKinds::new(BTreeMap::new(), BTreeMap::new());
998 let ukind = UsrKindId::new(1, Some("nams"), None);
999 res!(uks.add(ukind.clone()));
1000 let jdat_dec = DecoderConfig::<_, _>::jdat(Some(uks));
1001 let input = "{1:{5:2,3:4}}";
1002 let expected = mapdat!{
1003 1u8 => best_mapdat!{
1004 5 => 2,
1005 3 => 4,
1006 },
1007 };
1008 let dat = res!(Dat::decode_string_with_config(input, &jdat_dec));
1009 test!("input:");
1010 for line in Stringer::new(input.to_string()).to_lines(" ") {
1011 test!("{}", line);
1012 }
1013 test!("result:");
1014 for line in Stringer::new(fmt!("{:?}", dat)).to_lines(" ") {
1015 test!("{}", line);
1016 }
1017 test!("expected:");
1018 for line in Stringer::new(fmt!("{:?}", expected)).to_lines(" ") {
1019 test!("{}", line);
1020 }
1021 req!(dat, expected);
1022 Ok(())
1023 }));
1024
1025 res!(test_it(filter, &["String decoding 685", "all", "map", "usr"], || {
1026 let mut uks = UsrKinds::new(BTreeMap::new(), BTreeMap::new());
1027 let ukind = UsrKindId::new(1, Some("nams"), None);
1028 res!(uks.add(ukind.clone()));
1029 let jdat_dec = DecoderConfig::<_, _>::jdat(Some(uks));
1030 let input = "{1:{(empty):2,3:4}}";
1031 let expected = mapdat!{
1032 1u8 => best_mapdat!{
1033 () => 2,
1034 3 => 4,
1035 },
1036 };
1037 let dat = res!(Dat::decode_string_with_config(input, &jdat_dec));
1038 test!("input:");
1039 for line in Stringer::new(input.to_string()).to_lines(" ") {
1040 test!("{}", line);
1041 }
1042 test!("result:");
1043 for line in Stringer::new(fmt!("{:?}", dat)).to_lines(" ") {
1044 test!("{}", line);
1045 }
1046 test!("expected:");
1047 for line in Stringer::new(fmt!("{:?}", expected)).to_lines(" ") {
1048 test!("{}", line);
1049 }
1050 req!(dat, expected);
1051 Ok(())
1052 }));
1053
1054 res!(test_it(filter, &["String decoding 686", "all", "map", "usr"], || {
1055 let mut uks = UsrKinds::new(BTreeMap::new(), BTreeMap::new());
1056 let ukind = UsrKindId::new(1, Some("nams"), None);
1057 res!(uks.add(ukind.clone()));
1058 let jdat_dec = DecoderConfig::<_, _>::jdat(Some(uks));
1059 let input = "{1:{(nams):2,3:4}}";
1060 let expected = mapdat!{
1061 1u8 => mapdat!{
1062 res!(Dat::try_from((ukind, None))) => 2u8,
1063 3u8 => 4u8,
1064 },
1065 };
1066 let dat = res!(Dat::decode_string_with_config(input, &jdat_dec));
1067 test!("input:");
1068 for line in Stringer::new(input.to_string()).to_lines(" ") {
1069 test!("{}", line);
1070 }
1071 test!("result:");
1072 for line in Stringer::new(fmt!("{:?}", dat)).to_lines(" ") {
1073 test!("{}", line);
1074 }
1075 test!("expected:");
1076 for line in Stringer::new(fmt!("{:?}", expected)).to_lines(" ") {
1077 test!("{}", line);
1078 }
1079 req!(dat, expected);
1080 Ok(())
1081 }));
1082
1083 res!(test_it(filter, &["String decoding 690", "all", "map", "usr"], || {
1084 // A map carried as the payload of a non-map user kind, whose own values are themselves
1085 // maps or lists. The nested `{` value used to inherit the parent's user kind as its
1086 // outer kind, leaving the value's frame with no map capture: a non-empty nested map hit
1087 // "Map capture not active" at the colon, an empty one "Map capture not actived" at the
1088 // closing brace. Each shape is checked for the exact decoded structure and for a full
1089 // decode -> re-encode -> decode round trip.
1090 let mut uks = UsrKinds::new(BTreeMap::new(), BTreeMap::new());
1091 let ukind = UsrKindId::new(1, Some("node"), None);
1092 res!(uks.add(ukind.clone()));
1093 let jdat_dec = DecoderConfig::<_, _>::jdat(Some(uks));
1094
1095 // Non-empty nested map value (the reported failure).
1096 let dat = res!(Dat::decode_string_with_config("(node|{\"a\":{\"x\":1},\"b\":2})", &jdat_dec));
1097 req!(dat, mapdat!{
1098 "a".to_string() => mapdat!{ "x".to_string() => 1u8 },
1099 "b".to_string() => 2u8,
1100 });
1101 req!(res!(Dat::decode_string(&res!(dat.jdat()))), dat); // round trip
1102
1103 // Empty nested map value.
1104 let dat = res!(Dat::decode_string_with_config("(node|{\"a\":{},\"b\":1})", &jdat_dec));
1105 req!(dat, mapdat!{
1106 "a".to_string() => mapdat!{},
1107 "b".to_string() => 1u8,
1108 });
1109 req!(res!(Dat::decode_string(&res!(dat.jdat()))), dat);
1110
1111 // Empty nested list value, and a deeper mixture, still under the user kind.
1112 let dat = res!(Dat::decode_string_with_config(
1113 "(node|{\"a\":{},\"b\":[],\"c\":{\"d\":1}})", &jdat_dec));
1114 req!(dat, mapdat!{
1115 "a".to_string() => mapdat!{},
1116 "b".to_string() => listdat![],
1117 "c".to_string() => mapdat!{ "d".to_string() => 1u8 },
1118 });
1119 req!(res!(Dat::decode_string(&res!(dat.jdat()))), dat);
1120
1121 // Control: a list value under the user kind already decoded correctly and must stay so.
1122 let dat = res!(Dat::decode_string_with_config("(node|{\"a\":[1],\"b\":2})", &jdat_dec));
1123 req!(dat, mapdat!{
1124 "a".to_string() => listdat![1u8],
1125 "b".to_string() => 2u8,
1126 });
1127
1128 // Control: the same nesting without a user kind must keep decoding as before.
1129 let dat = res!(Dat::decode_string("{\"a\":{\"x\":1},\"b\":2}"));
1130 req!(dat, mapdat!{
1131 "a".to_string() => mapdat!{ "x".to_string() => 1u8 },
1132 "b".to_string() => 2u8,
1133 });
1134
1135 // Control: an explicitly declared ordered map keeps its ordered kind through the fix.
1136 let dat = res!(Dat::decode_string("(omap|{\"a\":(omap|{\"x\":1}),\"b\":2})"));
1137 req!(dat, omapdat!{
1138 "a".to_string() => omapdat!{ "x".to_string() => 1u8 },
1139 "b".to_string() => 2u8,
1140 });
1141 Ok(())
1142 }));
1143
1144 res!(test_it(filter, &["String decoding 691", "all", "map", "usr"], || {
1145 // A molecular payload carried by a non-map user kind as a *nested value* used to be
1146 // silently dropped on text decode. Under the fix at close_paren, the payload captured a
1147 // level down survives instead of being overwritten with a bare `(node)`:
1148 // - as a map value, `(node|{...})` kept its inner map (was `(node)`, payload lost);
1149 // - as a unitary value, `(node|(node|{...}))` kept the inner payload too.
1150 // Each shape is checked for the exact decoded structure and a decode -> re-encode ->
1151 // decode round trip.
1152 let mut uks = UsrKinds::new(BTreeMap::new(), BTreeMap::new());
1153 let ukind = UsrKindId::new(1, Some("node"), None);
1154 res!(uks.add(ukind.clone()));
1155 let jdat_dec = DecoderConfig::<_, _>::jdat(Some(uks));
1156
1157 // The reported failure: a `(node|{...})` map value. Its inner map used to vanish,
1158 // leaving `(node)`.
1159 let dat = res!(Dat::decode_string_with_config(
1160 "(node|{\"a\":(node|{\"x\":1}),\"b\":2})", &jdat_dec));
1161 req!(dat, mapdat!{
1162 "a".to_string() => mapdat!{ "x".to_string() => 1u8 },
1163 "b".to_string() => 2u8,
1164 });
1165 req!(res!(Dat::decode_string_with_config(&res!(dat.jdat()), &jdat_dec)), dat); // round trip
1166
1167 // The `(node|(node|{...}))` form: the inner molecular payload used to vanish too, leaving
1168 // `(node|(node))`. The inner user kind resolves to its bare map payload, kept under the
1169 // outer kind. (No round trip here: a top-level `(node|{...})` re-decodes to a bare map,
1170 // an existing asymmetry unrelated to this fix, so the shape is not a fixed point.)
1171 let dat = res!(Dat::decode_string_with_config("(node|(node|{\"x\":1}))", &jdat_dec));
1172 req!(dat, Dat::Usr(ukind.clone(), Some(Box::new(mapdat!{
1173 "x".to_string() => 1u8,
1174 }))));
1175
1176 // Several sibling user-kind map values, each carrying its own map molecule, and a
1177 // deeper level of the same nesting.
1178 let dat = res!(Dat::decode_string_with_config(
1179 "(node|{\"a\":(node|{\"c\":3}),\"b\":(node|{\"d\":(node|{\"e\":4})})})", &jdat_dec));
1180 req!(dat, mapdat!{
1181 "a".to_string() => mapdat!{ "c".to_string() => 3u8 },
1182 "b".to_string() => mapdat!{
1183 "d".to_string() => mapdat!{ "e".to_string() => 4u8 },
1184 },
1185 });
1186 req!(res!(Dat::decode_string_with_config(&res!(dat.jdat()), &jdat_dec)), dat);
1187
1188 // The list analogue: a `(node|[...])` value must keep its list payload, exactly as the
1189 // `(node|{...})` map value keeps its map. Previously this hard-errored with "Found a
1190 // '[' which is incompatible".
1191 let dat = res!(Dat::decode_string_with_config(
1192 "(node|{\"a\":(node|[1,2]),\"b\":2})", &jdat_dec));
1193 req!(dat, mapdat!{
1194 "a".to_string() => listdat![1u8, 2u8],
1195 "b".to_string() => 2u8,
1196 });
1197 req!(res!(Dat::decode_string_with_config(&res!(dat.jdat()), &jdat_dec)), dat);
1198
1199 // A `(node|[...])` list value sitting beside a `(node|{...})` map value, so both molecule
1200 // shapes are exercised under the one user kind.
1201 let dat = res!(Dat::decode_string_with_config(
1202 "(node|{\"a\":(node|[1,2]),\"b\":(node|{\"c\":3})})", &jdat_dec));
1203 req!(dat, mapdat!{
1204 "a".to_string() => listdat![1u8, 2u8],
1205 "b".to_string() => mapdat!{ "c".to_string() => 3u8 },
1206 });
1207 req!(res!(Dat::decode_string_with_config(&res!(dat.jdat()), &jdat_dec)), dat);
1208
1209 // The `(node|(node|[...]))` unitary form keeps the inner list payload under the outer
1210 // kind, mirroring the map case above.
1211 let dat = res!(Dat::decode_string_with_config("(node|(node|[1,2]))", &jdat_dec));
1212 req!(dat, Dat::Usr(ukind.clone(), Some(Box::new(listdat![1u8, 2u8]))));
1213
1214 // Control: a dataless `(node)` value with no payload is untouched by the fix.
1215 let dat = res!(Dat::decode_string_with_config("(node|{\"a\":(node),\"b\":2})", &jdat_dec));
1216 req!(dat, mapdat!{
1217 "a".to_string() => res!(Dat::try_from((ukind.clone(), None))),
1218 "b".to_string() => 2u8,
1219 });
1220 Ok(())
1221 }));
1222
1223 res!(test_it(filter, &["String decoding 692", "all", "map", "usr"], || {
1224 // A user-kind value carrying a molecular payload -- `(node|{...})` or `(node|[...])` --
1225 // sitting as a VALUE inside a PLAIN map, whose own outer kind is a map, not a user kind.
1226 // The payload decoded a level down and the wrapper's closing `)` was left for the plain
1227 // map frame, where close_paren rejected it ("should have triggered ListMixed ... Some(Map)")
1228 // because the frame is capturing a map, not a mixed list. Distinct from "String decoding
1229 // 690"/"691", where the payload sits UNDER a user kind (the outer kind is `(node|...)`).
1230 // Each shape is checked for the exact structure and a decode -> re-encode -> decode trip.
1231 let mut uks = UsrKinds::new(BTreeMap::new(), BTreeMap::new());
1232 let ukind = UsrKindId::new(1, Some("node"), None);
1233 res!(uks.add(ukind.clone()));
1234 let jdat_dec = DecoderConfig::<_, _>::jdat(Some(uks));
1235
1236 // The reported failure: a `(node|{...})` map value in a plain map.
1237 let dat = res!(Dat::decode_string_with_config("{\"a\":(node|{\"x\":1})}", &jdat_dec));
1238 req!(dat, mapdat!{
1239 "a".to_string() => mapdat!{ "x".to_string() => 1u8 },
1240 });
1241 req!(res!(Dat::decode_string_with_config(&res!(dat.jdat()), &jdat_dec)), dat); // round trip
1242
1243 // The list analogue: a `(node|[...])` list value in a plain map.
1244 let dat = res!(Dat::decode_string_with_config("{\"a\":(node|[1,2])}", &jdat_dec));
1245 req!(dat, mapdat!{
1246 "a".to_string() => listdat![1u8, 2u8],
1247 });
1248 req!(res!(Dat::decode_string_with_config(&res!(dat.jdat()), &jdat_dec)), dat);
1249
1250 // Siblings of both molecule shapes, with a plain value between them, all in the one map.
1251 let dat = res!(Dat::decode_string_with_config(
1252 "{\"a\":(node|{\"x\":1}),\"b\":2,\"c\":(node|[3,4])}", &jdat_dec));
1253 req!(dat, mapdat!{
1254 "a".to_string() => mapdat!{ "x".to_string() => 1u8 },
1255 "b".to_string() => 2u8,
1256 "c".to_string() => listdat![3u8, 4u8],
1257 });
1258 req!(res!(Dat::decode_string_with_config(&res!(dat.jdat()), &jdat_dec)), dat);
1259
1260 // Nested: the `(node|{...})` value sits inside a nested plain map value, not the outer one.
1261 let dat = res!(Dat::decode_string_with_config(
1262 "{\"a\":{\"b\":(node|{\"x\":1})}}", &jdat_dec));
1263 req!(dat, mapdat!{
1264 "a".to_string() => mapdat!{
1265 "b".to_string() => mapdat!{ "x".to_string() => 1u8 },
1266 },
1267 });
1268 req!(res!(Dat::decode_string_with_config(&res!(dat.jdat()), &jdat_dec)), dat);
1269 Ok(())
1270 }));
1271
1272 res!(test_it(filter, &["String integrated decoding 000", "all", "map"], || {
1273 let d = res!(Dat::decode_string("
1274 {
1275 \"1\":{
1276 2:(I16|-3),
1277 4:[5,6],
1278 },
1279 }"));
1280 let expected = mapdat!{
1281 "1".to_string() => mapdat!{
1282 2u8 => -3i16,
1283 4u8 => listdat![
1284 5u8,
1285 6u8,
1286 ],
1287 },
1288 };
1289 for line in expected.to_lines(" ", true) {
1290 test!("{}", line);
1291 }
1292 req!(d, expected);
1293 Ok(())
1294 }));
1295
1296 res!(test_it(filter, &["String integrated decoding 010", "all", "map", "abox"], || {
1297 let expected = dat!(mapdat!{
1298 mapdat!{
1299 "1".to_string() => mapdat!{
1300 2u8 => -3i16,
1301 4u8 => listdat![
1302 5u8,
1303 6u8,
1304 ],
1305 },
1306 "10".to_string() => 11u8,
1307 } => mapdat!{
1308 12u32 => false,
1309 13i8 => true,
1310 },
1311 dat!(14u8) => abox!((), "This is the number 14"),
1312 300u16 => dat!(7u8),
1313 });
1314 for line in expected.to_lines(" ", true) {
1315 test!("{}", line);
1316 }
1317 let d = res!(Dat::decode_string("
1318 {
1319 {
1320 \"1\":{
1321 2:(I16|-3),
1322 4:[5,6],
1323 },
1324 \"10\":(U8|11),
1325 }:{
1326 (U32|12):(FALSE),
1327 (I8|13):true,
1328 },
1329 14: !This is the number 14!,
1330 300: (U8|7),
1331 }"));
1332 req!(d, expected);
1333 Ok(())
1334 }));
1335
1336 res!(test_it(filter, &["String config file 000", "all", "map", "file"], || {
1337 // Reference JDAT text that a stored o3db config file would contain.
1338 let s = r#"(omap|{
1339 (str|"num_zones"): (u16|2),
1340 (str|"num_caches"): (u16|2),
1341 (str|"num_readers"): (u16|2),
1342 (str|"cache_size_limit_mb"): (u64|1000),
1343 (str|"data_file_max_bytes"): (u64|1000),
1344 (str|"index_file_max_bytes"): (u64|1000),
1345 (str|"zones"): (omap|{
1346 (list|[
1347 (u16|0),
1348 ]): (list|[
1349 (str|"./"),
1350 (u8|1),
1351 (u16|100),
1352 ]),
1353 (list|[
1354 (u16|1),
1355 ]): (list|[
1356 (str|"./"),
1357 (u8|1),
1358 (u16|100),
1359 ]),
1360 }),
1361})"#;
1362 let dat = res!(Dat::decode_string(s));
1363 let expected = omapdat!{
1364 "num_zones" => 2u16,
1365 "num_caches" => 2u16,
1366 "num_readers" => 2u16,
1367 "cache_size_limit_mb" => 1000u64,
1368 "data_file_max_bytes" => 1000u64,
1369 "index_file_max_bytes" => 1000u64,
1370 "zones" => omapdat!{
1371 listdat![0u16] => listdat![
1372 "./", 1u8, 100u16,
1373 ],
1374 listdat![1u16] => listdat![
1375 "./", 1u8, 100u16,
1376 ],
1377 },
1378 };
1379 req!(dat, expected);
1380 Ok(())
1381 }));
1382
1383 res!(test_it(filter, &["String encode decode 000", "all", "usr"], || {
1384 let ukind = UsrKindId::new(5, Some("my_type"), Some(Kind::I32));
1385 let d0 = dat!(42);
1386 let d1 = Dat::Usr(ukind, Some(Box::new(d0.clone())));
1387 req!(fmt!("{:?}", d1), "(my_type|(i32|42))", "(L: debug output, R: expected)");
1388 req!(fmt!("{}", d1), "(my_type|(i32|42))", "(L: display output, R: expected)");
1389 Ok(())
1390 }));
1391
1392 res!(test_it(filter, &["String encode decode 010", "all", "box"], || {
1393 let d0 = dat!(42);
1394 let d1 = Dat::Opt(Box::new(Some(d0)));
1395 let d1_str = fmt!("{:?}", d1);
1396 test!("{}", d1_str);
1397 let d2 = res!(Dat::decode_string(d1_str));
1398 req!(d1, d2, "(L: expected, R: decoded)");
1399 Ok(())
1400 }));
1401
1402 res!(test_it(filter, &["String encode decode 020", "all", "opt"], || {
1403 let d1 = Dat::Opt(Box::new(None));
1404 let d1_str = fmt!("{:?}", d1);
1405 test!("{}", d1_str);
1406 let d2 = res!(Dat::decode_string(d1_str));
1407 req!(d1, d2, "(L: expected, R: decoded)");
1408 Ok(())
1409 }));
1410
1411 res!(test_it(filter, &["String encode decode 030", "all", "bc64"], || {
1412 let byts = vec![1u8,2,3,4,5];
1413 let d1 = Dat::BC64(byts);
1414 let d1_str = fmt!("{:?}", d1);
1415 test!("{}", d1_str);
1416 let d2 = res!(Dat::decode_string(d1_str));
1417 req!(d1, d2, "(L: expected, R: decoded)");
1418 Ok(())
1419 }));
1420
1421 res!(test_it(filter, &["String encode decode 040", "all", "i16"], || {
1422 let jdat_enc = EncoderConfig::<(), ()>::jdat(None);
1423 let jdat_dec = DecoderConfig::<(), ()>::jdat(None);
1424 let d1 = Dat::I16(-3957i16);
1425 let d1_str = res!(d1.encode_string_with_config(&jdat_enc));
1426 test!("{}", d1_str);
1427 test!("jdat = {}", d1_str);
1428 let d2 = res!(Dat::decode_string_with_config(d1_str.clone(), &jdat_dec));
1429 req!(d1, d2, "(L: expected, R: decoded)");
1430 Ok(())
1431 }));
1432
1433 res!(test_it(filter, &["String encode decode 050", "all", "i16"], || {
1434 let jdat_enc = EncoderConfig::<(), ()>::jdat(None);
1435 let jdat_dec = DecoderConfig::<(), ()>::jdat(None);
1436 let d1 = Dat::I16(i16::MIN);
1437 let d1_str = res!(d1.encode_string_with_config(&jdat_enc));
1438 test!("{}", d1_str);
1439 test!("jdat = {}", d1_str);
1440 let d2 = res!(Dat::decode_string_with_config(d1_str.clone(), &jdat_dec));
1441 req!(d1, d2, "(L: expected, R: decoded)");
1442 Ok(())
1443 }));
1444
1445 res!(test_it(filter, &["String encode decode 060", "all", "i16"], || {
1446 let mut jdat_enc = EncoderConfig::<(), ()>::jdat(None);
1447 let jdat_dec = DecoderConfig::<(), ()>::jdat(None);
1448 jdat_enc.int_encoding = IntEncoding::Octal;
1449 let d1 = Dat::I16(-3957i16);
1450 let d1_str = res!(d1.encode_string_with_config(&jdat_enc));
1451 test!("{}", d1_str);
1452 test!("jdat = {}", d1_str);
1453 let d2 = res!(Dat::decode_string_with_config(d1_str.clone(), &jdat_dec));
1454 req!(d1, d2, "(L: expected, R: decoded)");
1455 Ok(())
1456 }));
1457
1458 res!(test_it(filter, &["String encode decode 070", "all", "i16"], || {
1459 let mut jdat_enc = EncoderConfig::<(), ()>::jdat(None);
1460 let jdat_dec = DecoderConfig::<(), ()>::jdat(None);
1461 jdat_enc.int_encoding = IntEncoding::Octal;
1462 let d1 = Dat::I16(i16::MIN);
1463 let d1_str = res!(d1.encode_string_with_config(&jdat_enc));
1464 test!("{}", d1_str);
1465 test!("jdat = {}", d1_str);
1466 let d2 = res!(Dat::decode_string_with_config(d1_str.clone(), &jdat_dec));
1467 req!(d1, d2, "(L: expected, R: decoded)");
1468 Ok(())
1469 }));
1470
1471 res!(test_it(filter, &["String encode decode 080", "all", "i16"], || {
1472 let mut jdat_enc = EncoderConfig::<(), ()>::jdat(None);
1473 let jdat_dec = DecoderConfig::<(), ()>::jdat(None);
1474 jdat_enc.int_encoding = IntEncoding::Binary;
1475 let d1 = Dat::I16(-3957i16);
1476 let d1_str = res!(d1.encode_string_with_config(&jdat_enc));
1477 test!("{}", d1_str);
1478 test!("jdat = {}", d1_str);
1479 let d2 = res!(Dat::decode_string_with_config(d1_str.clone(), &jdat_dec));
1480 req!(d1, d2, "(L: expected, R: decoded)");
1481 Ok(())
1482 }));
1483
1484 res!(test_it(filter, &["String encode decode 090", "all", "i16"], || {
1485 let mut jdat_enc = EncoderConfig::<(), ()>::jdat(None);
1486 let jdat_dec = DecoderConfig::<(), ()>::jdat(None);
1487 jdat_enc.int_encoding = IntEncoding::Binary;
1488 let d1 = Dat::I16(i16::MIN);
1489 let d1_str = res!(d1.encode_string_with_config(&jdat_enc));
1490 test!("{}", d1_str);
1491 test!("jdat = {}", d1_str);
1492 let d2 = res!(Dat::decode_string_with_config(d1_str.clone(), &jdat_dec));
1493 req!(d1, d2, "(L: expected, R: decoded)");
1494 Ok(())
1495 }));
1496
1497 res!(test_it(filter, &["String encode decode 100", "all", "b32"], || {
1498 let jdat_enc = EncoderConfig::<(), ()>::jdat(None);
1499 let jdat_dec = DecoderConfig::<(), ()>::jdat(None);
1500 let json_enc = EncoderConfig::<(), ()>::json(None);
1501 let byts = [
1502 0x9a, 0xc1, 0x78, 0x08, 0xc1, 0xb3, 0x5e, 0x4b,
1503 0xfe, 0xb9, 0x91, 0xa4, 0x3b, 0x04, 0x15, 0xb3,
1504 0x00, 0xb1, 0x66, 0xf5, 0x81, 0x08, 0xcc, 0x3d,
1505 0xa2, 0xab, 0x61, 0x8d, 0xd9, 0xcc, 0xf0, 0x38,
1506 ];
1507 let d1 = Dat::B32(B32(byts));
1508 let d1_str = res!(d1.encode_string_with_config(&jdat_enc));
1509 test!("jdat = {}", d1_str);
1510 test!("json = {}", res!(d1.encode_string_with_config(&json_enc)));
1511 let d2 = res!(Dat::decode_string_with_config(d1_str.clone(), &jdat_dec));
1512 req!(d1, d2, "(L: expected, R: decoded)");
1513 Ok(())
1514 }));
1515
1516 res!(test_it(filter, &["String encode decode 110", "all", "bu8"], || {
1517 let jdat_enc = EncoderConfig::<(), ()>::jdat(None);
1518 let jdat_dec = DecoderConfig::<(), ()>::jdat(None);
1519 let json_enc = EncoderConfig::<(), ()>::json(None);
1520 let byts = [
1521 0x9a, 0xc1, 0x78, 0x08, 0xc1, 0xb3, 0x5e, 0x4b,
1522 0xfe, 0xb9, 0x91, 0xa4, 0x3b, 0x04, 0x15, 0xb3,
1523 0x00, 0xb1, 0x66, 0xf5, 0x81, 0x08, 0xcc, 0x3d,
1524 0xa2, 0xab, 0x61, 0x8d, 0xd9, 0xcc, 0xf0, 0x38,
1525 ];
1526 let d1 = Dat::BU8(byts.to_vec());
1527 let d1_str = res!(d1.encode_string_with_config(&jdat_enc));
1528 test!("jdat = {}", d1_str);
1529 test!("json = {}", res!(d1.encode_string_with_config(&json_enc)));
1530 let d2 = res!(Dat::decode_string_with_config(d1_str.clone(), &jdat_dec));
1531 req!(d1, d2, "(L: expected, R: decoded)");
1532 Ok(())
1533 }));
1534
1535 res!(test_it(filter, &["String encode decode 120", "all", "bu64"], || {
1536 let json_enc = EncoderConfig::<(), ()>::json(None);
1537 let json_dec = DecoderConfig::<(), ()>::json(None);
1538 let byts = vec![1u8, 2, 3, 4, 5];
1539 let d1 = Dat::BU64(byts);
1540 let d3 = listdat![1u8, 2u8, 3u8, 4u8, 5u8];
1541 let d1_str = res!(d1.encode_string_with_config(&json_enc));
1542 test!("json = {}", d1_str);
1543 let d2 = res!(Dat::decode_string_with_config(d1_str.clone(), &json_dec));
1544 req!(d1_str, "[1, 2, 3, 4, 5]".to_string());
1545 req!(d2, d3);
1546 Ok(())
1547 }));
1548
1549 res!(test_it(filter, &["String encode decode 130", "all", "bu64"], || {
1550 let jdat_enc = EncoderConfig::<(), ()>::jdat(None);
1551 let jdat_dec = DecoderConfig::<(), ()>::jdat(None);
1552 let byts = vec![1u8,2,3,4,5];
1553 let d1 = Dat::BU64(byts);
1554 let d1_str = res!(d1.encode_string_with_config(&jdat_enc));
1555 test!("jdat = {}", d1_str);
1556 let d2 = res!(Dat::decode_string_with_config(d1_str, &jdat_dec));
1557 req!(d1, d2);
1558 Ok(())
1559 }));
1560
1561 res!(test_it(filter, &["String encode decode 140", "all", "tuple"], || {
1562 test_string_encode_decode_homogenous_tuple! { jdat, [42u8; 2] }
1563 Ok(())
1564 }));
1565 res!(test_it(filter, &["String encode decode 150", "all", "tuple"], || {
1566 test_string_encode_decode_homogenous_tuple! { jdat, [42u8; 3] }
1567 Ok(())
1568 }));
1569 res!(test_it(filter, &["String encode decode 160", "all", "tuple"], || {
1570 test_string_encode_decode_homogenous_tuple! { jdat, [42u8; 4] }
1571 Ok(())
1572 }));
1573 res!(test_it(filter, &["String encode decode 170", "all", "tuple"], || {
1574 test_string_encode_decode_homogenous_tuple! { jdat, [42u8; 5] }
1575 Ok(())
1576 }));
1577 res!(test_it(filter, &["String encode decode 180", "all", "tuple"], || {
1578 test_string_encode_decode_homogenous_tuple! { jdat, [42u8; 6] }
1579 Ok(())
1580 }));
1581 res!(test_it(filter, &["String encode decode 190", "all", "tuple"], || {
1582 test_string_encode_decode_homogenous_tuple! { jdat, [42u8; 7] }
1583 Ok(())
1584 }));
1585 res!(test_it(filter, &["String encode decode 200", "all", "tuple"], || {
1586 test_string_encode_decode_homogenous_tuple! { jdat, [42u8; 8] }
1587 Ok(())
1588 }));
1589 res!(test_it(filter, &["String encode decode 210", "all", "tuple"], || {
1590 test_string_encode_decode_homogenous_tuple! { jdat, [42u8; 9] }
1591 Ok(())
1592 }));
1593 res!(test_it(filter, &["String encode decode 220", "all", "tuple"], || {
1594 test_string_encode_decode_homogenous_tuple! { jdat, [42u8; 10] }
1595 Ok(())
1596 }));
1597 res!(test_it(filter, &["String encode decode 230", "all", "tuple"], || {
1598 test_string_encode_decode_homogenous_tuple! { jdat, [42u8; 16] }
1599 Ok(())
1600 }));
1601 res!(test_it(filter, &["String encode decode 240", "all", "tuple"], || {
1602 test_string_encode_decode_homogenous_tuple! { jdat, [42u8; 32] }
1603 Ok(())
1604 }));
1605
1606 res!(test_it(filter, &["String encode decode 250", "all", "tuple"], || {
1607 test_string_encode_decode_homogenous_tuple! { jdat, [42u16; 2] }
1608 Ok(())
1609 }));
1610 res!(test_it(filter, &["String encode decode 260", "all", "tuple"], || {
1611 test_string_encode_decode_homogenous_tuple! { jdat, [42u16; 3] }
1612 Ok(())
1613 }));
1614 res!(test_it(filter, &["String encode decode 270", "all", "tuple"], || {
1615 test_string_encode_decode_homogenous_tuple! { jdat, [42u16; 4] }
1616 Ok(())
1617 }));
1618 res!(test_it(filter, &["String encode decode 280", "all", "tuple"], || {
1619 test_string_encode_decode_homogenous_tuple! { jdat, [42u16; 5] }
1620 Ok(())
1621 }));
1622 res!(test_it(filter, &["String encode decode 290", "all", "tuple"], || {
1623 test_string_encode_decode_homogenous_tuple! { jdat, [42u16; 6] }
1624 Ok(())
1625 }));
1626 res!(test_it(filter, &["String encode decode 300", "all", "tuple"], || {
1627 test_string_encode_decode_homogenous_tuple! { jdat, [42u16; 7] }
1628 Ok(())
1629 }));
1630 res!(test_it(filter, &["String encode decode 310", "all", "tuple"], || {
1631 test_string_encode_decode_homogenous_tuple! { jdat, [42u16; 8] }
1632 Ok(())
1633 }));
1634 res!(test_it(filter, &["String encode decode 320", "all", "tuple"], || {
1635 test_string_encode_decode_homogenous_tuple! { jdat, [42u16; 9] }
1636 Ok(())
1637 }));
1638 res!(test_it(filter, &["String encode decode 330", "all", "tuple"], || {
1639 test_string_encode_decode_homogenous_tuple! { jdat, [42u16; 10] }
1640 Ok(())
1641 }));
1642
1643 res!(test_it(filter, &["String encode decode 340", "all", "tuple"], || {
1644 test_string_encode_decode_homogenous_tuple! { jdat, [42u32; 2] }
1645 Ok(())
1646 }));
1647 res!(test_it(filter, &["String encode decode 350", "all", "tuple"], || {
1648 test_string_encode_decode_homogenous_tuple! { jdat, [42u32; 3] }
1649 Ok(())
1650 }));
1651 res!(test_it(filter, &["String encode decode 360", "all", "tuple"], || {
1652 test_string_encode_decode_homogenous_tuple! { jdat, [42u32; 4] }
1653 Ok(())
1654 }));
1655 res!(test_it(filter, &["String encode decode 370", "all", "tuple"], || {
1656 test_string_encode_decode_homogenous_tuple! { jdat, [42u32; 5] }
1657 Ok(())
1658 }));
1659 res!(test_it(filter, &["String encode decode 380", "all", "tuple"], || {
1660 test_string_encode_decode_homogenous_tuple! { jdat, [42u32; 6] }
1661 Ok(())
1662 }));
1663 res!(test_it(filter, &["String encode decode 390", "all", "tuple"], || {
1664 test_string_encode_decode_homogenous_tuple! { jdat, [42u32; 7] }
1665 Ok(())
1666 }));
1667 res!(test_it(filter, &["String encode decode 400", "all", "tuple"], || {
1668 test_string_encode_decode_homogenous_tuple! { jdat, [42u32; 8] }
1669 Ok(())
1670 }));
1671 res!(test_it(filter, &["String encode decode 410", "all", "tuple"], || {
1672 test_string_encode_decode_homogenous_tuple! { jdat, [42u32; 9] }
1673 Ok(())
1674 }));
1675 res!(test_it(filter, &["String encode decode 420", "all", "tuple"], || {
1676 test_string_encode_decode_homogenous_tuple! { jdat, [42u32; 10] }
1677 Ok(())
1678 }));
1679
1680 res!(test_it(filter, &["String encode decode 430", "all", "tuple"], || {
1681 test_string_encode_decode_homogenous_tuple! { jdat, [42u64; 2] }
1682 Ok(())
1683 }));
1684 res!(test_it(filter, &["String encode decode 440", "all", "tuple"], || {
1685 test_string_encode_decode_homogenous_tuple! { jdat, [42u64; 3] }
1686 Ok(())
1687 }));
1688 res!(test_it(filter, &["String encode decode 450", "all", "tuple"], || {
1689 test_string_encode_decode_homogenous_tuple! { jdat, [42u64; 4] }
1690 Ok(())
1691 }));
1692 res!(test_it(filter, &["String encode decode 460", "all", "tuple"], || {
1693 test_string_encode_decode_homogenous_tuple! { jdat, [42u64; 5] }
1694 Ok(())
1695 }));
1696 res!(test_it(filter, &["String encode decode 470", "all", "tuple"], || {
1697 test_string_encode_decode_homogenous_tuple! { jdat, [42u64; 6] }
1698 Ok(())
1699 }));
1700 res!(test_it(filter, &["String encode decode 480", "all", "tuple"], || {
1701 test_string_encode_decode_homogenous_tuple! { jdat, [42u64; 7] }
1702 Ok(())
1703 }));
1704 res!(test_it(filter, &["String encode decode 490", "all", "tuple"], || {
1705 test_string_encode_decode_homogenous_tuple! { jdat, [42u64; 8] }
1706 Ok(())
1707 }));
1708 res!(test_it(filter, &["String encode decode 500", "all", "tuple"], || {
1709 test_string_encode_decode_homogenous_tuple! { jdat, [42u64; 9] }
1710 Ok(())
1711 }));
1712 res!(test_it(filter, &["String encode decode 510", "all", "tuple"], || {
1713 test_string_encode_decode_homogenous_tuple! { jdat, [42u64; 10] }
1714 Ok(())
1715 }));
1716
1717 res!(test_it(filter, &["String encode decode 600", "all", "usr"], || {
1718 let mut ukinds = UsrKinds::new(BTreeMap::new(), BTreeMap::new());
1719 let k1 = UsrKindId::new(5, Some("test1"), Some(Kind::Str));
1720 let k2 = UsrKindId::new(3, Some("test2"), None);
1721 let k3 = UsrKindId::new(7, Some("test3"), Some(Kind::U8));
1722 res!(ukinds.add(k1.clone()));
1723 res!(ukinds.add(k2.clone()));
1724 res!(ukinds.add(k3.clone()));
1725 let jdat_enc = EncoderConfig::jdat(Some(ukinds.clone()));
1726 let jdat_dec = DecoderConfig::jdat(Some(ukinds));
1727
1728 let d1_enc = res!(Dat::try_from((k1, Some(dat!("hello")))));
1729 let d1_enc_str = res!(d1_enc.encode_string_with_config(&jdat_enc));
1730 test!("jdat enc = {}", d1_enc_str);
1731 let d1_dec = res!(Dat::decode_string_with_config(d1_enc_str, &jdat_dec));
1732 // Debug has no knowledge of usr kinds.
1733 let d1_dec_str = res!(d1_dec.encode_string_with_config(&jdat_enc));
1734 test!("jdat dec = {}", d1_dec_str);
1735 req!(d1_enc, d1_dec);
1736
1737 let d2_enc = res!(Dat::try_from((k2, None)));
1738 let d2_enc_str = res!(d2_enc.encode_string_with_config(&jdat_enc));
1739 test!("jdat enc = {}", d2_enc_str);
1740 let d2_dec = res!(Dat::decode_string_with_config(d2_enc_str, &jdat_dec));
1741 // Debug has no knowledge of usr kinds.
1742 let d2_dec_str = res!(d2_dec.encode_string_with_config(&jdat_enc));
1743 test!("jdat dec = {}", d2_dec_str);
1744 req!(d2_enc, d2_dec);
1745
1746 let d3_enc = res!(Dat::try_from((k3, Some(dat!(42u8)))));
1747 let d3_enc_str = res!(d3_enc.encode_string_with_config(&jdat_enc));
1748 test!("jdat enc = {}", d3_enc_str);
1749 let d3_dec = res!(Dat::decode_string_with_config(d3_enc_str, &jdat_dec));
1750 // Debug has no knowledge of usr kinds.
1751 let d3_dec_str = res!(d3_dec.encode_string_with_config(&jdat_enc));
1752 test!("jdat dec = {}", d3_dec_str);
1753 req!(d3_enc, d3_dec);
1754 Ok(())
1755 }));
1756
1757 res!(test_it(filter, &["String encode decode 610", "all", "usr"], || {
1758 let mut ukinds = UsrKinds::new(BTreeMap::new(), BTreeMap::new());
1759 let k1 = UsrKindId::new(5, Some("test1"), Some(Kind::Str));
1760 let k2 = UsrKindId::new(3, Some("test2"), None);
1761 let k3 = UsrKindId::new(7, Some("test3"), Some(Kind::U8));
1762 res!(ukinds.add(k1.clone()));
1763 res!(ukinds.add(k2.clone()));
1764 res!(ukinds.add(k3.clone()));
1765 let json_enc = EncoderConfig::json(Some(ukinds.clone()));
1766 let json_dec = DecoderConfig::json(Some(ukinds));
1767
1768 let d1_enc = res!(Dat::try_from((k1, Some(dat!("hello")))));
1769 let d1_enc_str = res!(d1_enc.encode_string_with_config(&json_enc));
1770 test!("json enc = {}", d1_enc_str);
1771 let d1_dec = res!(Dat::decode_string_with_config(d1_enc_str.clone(), &json_dec));
1772 // Debug has no knowledge of usr kinds.
1773 let d1_dec_str = res!(d1_dec.encode_string_with_config(&json_enc));
1774 test!("json dec = {}", d1_dec_str);
1775 req!(&d1_enc_str, "\"hello\"");
1776
1777 let d2_enc = res!(Dat::try_from((k2, None)));
1778 let d2_enc_str = res!(d2_enc.encode_string_with_config(&json_enc));
1779 test!("json enc = {}", d2_enc_str);
1780 let d2_dec = res!(Dat::decode_string_with_config(d2_enc_str.clone(), &json_dec));
1781 // Debug has no knowledge of usr kinds.
1782 let d2_dec_str = res!(d2_dec.encode_string_with_config(&json_enc));
1783 test!("json dec = {}", d2_dec_str);
1784 req!(&d2_enc_str, "\"test2\"");
1785
1786 let d3_enc = res!(Dat::try_from((k3, Some(dat!(42u8)))));
1787 let d3_enc_str = res!(d3_enc.encode_string_with_config(&json_enc));
1788 test!("json enc = {}", d3_enc_str);
1789 let d3_dec = res!(Dat::decode_string_with_config(d3_enc_str.clone(), &json_dec));
1790 // Debug has no knowledge of usr kinds.
1791 let d3_dec_str = res!(d3_dec.encode_string_with_config(&json_enc));
1792 test!("json dec = {}", d3_dec_str);
1793 req!(&d3_enc_str, "42");
1794 Ok(())
1795 }));
1796
1797 res!(test_it(filter, &["String encode decode 620", "all", "usr"], || {
1798 let mut ukinds = UsrKinds::new(BTreeMap::new(), BTreeMap::new());
1799 let k1 = UsrKindId::new(5, Some("test1"), Some(Kind::Str));
1800 let k2 = UsrKindId::new(3, Some("test2"), None);
1801 let k3 = UsrKindId::new(7, Some("test3"), Some(Kind::U8));
1802 res!(ukinds.add(k1.clone()));
1803 res!(ukinds.add(k2.clone()));
1804 res!(ukinds.add(k3.clone()));
1805 let jdat_enc = EncoderConfig::jdat(Some(ukinds.clone()));
1806 //let jdat_dec = DecoderConfig::jdat(Some(ukinds));
1807
1808 let d1 = res!(Dat::try_from((k1, Some(dat!("hello")))));
1809 let d2 = res!(Dat::try_from((k2, None)));
1810 let d3 = res!(Dat::try_from((k3, Some(dat!(42u8)))));
1811
1812 let d4 = mapdat! {
1813 d1 => dat!("val1"),
1814 d2 => dat!("val2"),
1815 d3 => dat!("val3"),
1816 };
1817
1818 let d4_enc_str = res!(d4.encode_string_with_config(&jdat_enc));
1819
1820 // Verify that the key ordering is as expected, and refers to the UsrKindCode.
1821 let expected = [
1822 fmt!("{{"),
1823 fmt!("(test2): \"val2\","),
1824 fmt!("(test1|\"hello\"): \"val1\","),
1825 fmt!("(test3|(u8|42)): \"val3\","),
1826 fmt!("}}"),
1827 ];
1828
1829 test!("jdat enc:");
1830 let mut i: usize = 0;
1831 for line in &Stringer::new(d4_enc_str).to_lines("") {
1832 test!("{}", line);
1833 req!(*line, expected[i]);
1834 i += 1;
1835 }
1836 Ok(())
1837
1838 }));
1839
1840 res!(test_it(filter, &["Annotated Box encode", "all", "abox"], || {
1841 let d1 = Dat::ABox(
1842 NoteConfig::default(),
1843 Box::new(dat!(1u8)),
1844 fmt!(" This is a comment "),
1845 );
1846 req!(fmt!("{:?}", d1), "(abox|(u8|1) ! This is a comment !)");
1847 test!("{:?}", d1);
1848 req!(fmt!("{}", d1), "(u8|1) ! This is a comment !");
1849 test!("{}", d1);
1850 Ok(())
1851 }));
1852
1853 res!(test_it(filter, &["Annotated Box map decode 000", "all", "abox", "map"], || {
1854 let d = res!(Dat::decode_string("
1855 {
1856 1:2,
1857 :! A singleton comment keyed to the empty dat !,
1858 ! A self-keyed comment that can appear anywhere in the map
1859 3:4,
1860 }"));
1861 let lines = d.to_lines(" ", false);
1862 test!("Map with comments:");
1863 for line in &lines {
1864 test!("{}", line);
1865 }
1866 let expected = mapdat!{
1867 1u8 => 2u8,
1868 () => abox!((), "A singleton comment keyed to the empty dat "),
1869 abox!((), "A self-keyed comment that can appear anywhere in the map") => (),
1870 3u8 => 4u8,
1871 };
1872 req!(d, expected);
1873 Ok(())
1874 }));
1875
1876 res!(test_it(filter, &["Annotated Box list decode 000", "all", "abox", "list"], || {
1877 let d = res!(Dat::decode_string("
1878 [
1879 1,
1880 2,
1881 3 ! A comment !,
1882 ! Another comment !,
1883 ! A comment to the end of the line
1884 4,
1885 ]"));
1886 let lines = d.to_lines(" ", false);
1887 test!("List with comments:");
1888 for line in &lines {
1889 test!("{}", line);
1890 }
1891 let expected = listdat![
1892 1u8,
1893 2u8,
1894 abox!(3u8, "A comment "),
1895 abox!((), "Another comment "),
1896 abox!((), "A comment to the end of the line"),
1897 4u8,
1898 ];
1899 req!(d, expected);
1900 Ok(())
1901 }));
1902
1903 res!(test_it(filter, &["Annotated Box display encode decode 000", "all", "abox", "list"], || {
1904 let d0 = Dat::ABox(
1905 NoteConfig::default(),
1906 Box::new(dat!(2u8)),
1907 fmt!("This is a comment"),
1908 );
1909 let d1 = Dat::ABox(
1910 NoteConfig::default(),
1911 Box::new(Dat::Empty),
1912 fmt!("Another comment"),
1913 );
1914 let d5 = listdat![1u8, d0, 3u8, d1];
1915 let lines = d5.to_lines(" ", false);
1916 test!("List display with comments:");
1917 for line in &lines {
1918 test!("{}", line);
1919 }
1920 let d10 = res!(Dat::decode_string(fmt!("{}", d5)));
1921 req!(d5, d10);
1922 Ok(())
1923 }));
1924
1925 res!(test_it(filter, &["Annotated Box display encode decode 005", "all", "abox", "list"], || {
1926 let d0 = Dat::ABox(
1927 NoteConfig::default(),
1928 Box::new(dat!(2u8)),
1929 fmt!("This is a comment"),
1930 );
1931 let d1 = Dat::ABox(
1932 NoteConfig::default().set_type1(false),
1933 Box::new(Dat::Empty),
1934 fmt!("A type2 comment"),
1935 );
1936 let d5 = listdat![1u8, d0, 3u8, d1, 4u8];
1937 let lines = d5.to_lines(" ", false);
1938 test!("List display with comments:");
1939 for line in &lines {
1940 test!("{}", line);
1941 }
1942 let d10 = res!(Dat::decode_string(fmt!("{}", d5)));
1943 req!(d5, d10);
1944 Ok(())
1945 }));
1946
1947 res!(test_it(filter, &["Annotated Box display encode decode 010", "all", "abox", "list", "nested"], || {
1948 let d0 = Dat::ABox(
1949 NoteConfig::default(),
1950 Box::new(dat!(2u8)),
1951 fmt!("This is a comment"),
1952 );
1953 let d1 = Dat::ABox(
1954 NoteConfig::default(),
1955 Box::new(Dat::Empty),
1956 fmt!("Another comment"),
1957 );
1958 let d2 = Dat::ABox(
1959 NoteConfig::default(),
1960 Box::new(Dat::Empty),
1961 fmt!("Another line to add."),
1962 );
1963 let d5 = listdat![1u8, d0, 3u8, listdat![d1, d2, 4u8], 5u8];
1964 let lines = d5.to_lines(" ", false);
1965 test!("List display with comments:");
1966 for line in &lines {
1967 test!("{}", line);
1968 }
1969 let d10 = res!(Dat::decode_string(fmt!("{}", d5)));
1970 req!(d5, d10);
1971 Ok(())
1972 }));
1973
1974 res!(test_it(filter, &["Annotated Box display encode decode 050", "all", "abox", "map"], || {
1975 let d0 = Dat::ABox(
1976 NoteConfig::default(),
1977 Box::new(dat!(2u8)),
1978 fmt!("This is a comment"),
1979 );
1980 let d1 = Dat::ABox(
1981 NoteConfig::default(),
1982 Box::new(Dat::Empty),
1983 fmt!("Another comment"),
1984 );
1985 let d2 = Dat::ABox(
1986 NoteConfig::default().set_type1(false),
1987 Box::new(Dat::Empty),
1988 fmt!("A type2 comment"),
1989 );
1990 let d5 = mapdat!{1u8 => d0, d2 => 2u8, 3u8 => d1};
1991 let lines = d5.to_lines(" ", false);
1992 test!("Map display with comments:");
1993 for line in &lines {
1994 test!("{}", line);
1995 }
1996 let d10 = res!(Dat::decode_string(fmt!("{}", d5)));
1997 req!(d5, d10);
1998 Ok(())
1999 }));
2000
2001 res!(test_it(filter, &["Integrated multiline 000", "all", "abox", "list", "map"], || {
2002 let d1 = listdat![
2003 1u8,
2004 "two",
2005 omapdat!{
2006 () => abox!((), "A comment keyed to the empty daticle."),
2007 10u8 => abox!((), "A comment keyed to a non-empty daticle."),
2008 abox!((), "A full line comment which is the key, with an empty value daticle.") => (),
2009 3u8 => listdat![
2010 4u8,
2011 "five",
2012 6u8,
2013 ],
2014 11u8 => tup3dat![
2015 abox!((), "This is a 3-tuple with a comment."),
2016 12u8,
2017 13u8,
2018 ],
2019 },
2020 listdat![
2021 abox!((), "A line comment"),
2022 8u8,
2023 9u8,
2024 ],
2025 ];
2026 let expected = vec![
2027 "[",
2028 " 1,",
2029 " \"two\",",
2030 " (omap|{",
2031 " :! A comment keyed to the empty daticle.",
2032 " 10:! A comment keyed to a non-empty daticle.",
2033 " ! A full line comment which is the key, with an empty value daticle.",
2034 " 3: [",
2035 " 4,",
2036 " \"five\",",
2037 " 6",
2038 " ],",
2039 " 11: (t3|[",
2040 " ! This is a 3-tuple with a comment.",
2041 " 12,",
2042 " 13",
2043 " ])",
2044 " }),",
2045 " [",
2046 " ! A line comment",
2047 " 8,",
2048 " 9",
2049 " ]",
2050 "]",
2051 ];
2052 test!("{}", d1);
2053 let jdat_str = res!(d1.display_some_to_lines(" "));
2054 let d2 = res!(Dat::decode_string(jdat_str.clone()));
2055 let lines: Vec<&str> = jdat_str.lines().collect();
2056 test!("Display output:");
2057 for (i, line) in lines.iter().enumerate() {
2058 test!("{:03}: {}", i + 1, line);
2059 }
2060 test!("Expected output:");
2061 for (i, line) in expected.iter().enumerate() {
2062 test!("{:03}: {}", i + 1, line);
2063 }
2064 req!(lines.len(), expected.len(), "(L: actual len, R: expected len)");
2065 let mut c = 0;
2066 for line in lines {
2067 req!(line, expected[c].to_string(), "(L: encoded, R: expected) line {}", c + 1);
2068 c += 1;
2069 }
2070 let result2 = res!(d2.display_to_lines(" "));
2071 let lines: Vec<&str> = result2.split("\n").collect();
2072 test!("Display output:");
2073 for line in &lines {
2074 test!("{}", line);
2075 }
2076 req!(d1, d2, "(L: encoded, R: decoded)");
2077 Ok(())
2078 }));
2079
2080 res!(test_it(filter, &["Integrated multiline 010", "all", "abox", "omnibus"], || {
2081 let ukind_ipv4 = UsrKindId::new(5, Some("ipv4"), Some(Kind::B4));
2082 let mut ukinds = UsrKinds::new(BTreeMap::new(), BTreeMap::new());
2083 res!(ukinds.add(ukind_ipv4.clone()));
2084 let d1 = listdat![
2085 1u8,
2086 "two",
2087 omapdat!{
2088 abox!((), "Ordered maps are a great way to fix the order of a map,") => (),
2089 abox!((), "allowing, for example, you to position multiline comments") => (),
2090 abox!((), "where you want them.") => (),
2091 3u8 => listdat![
2092 4u8,
2093 "five",
2094 res!(Dat::try_from((ukind_ipv4.clone(), Some(Dat::B4([1,2,3,4]))))),
2095 6u8,
2096 ],
2097 11u8 => tup3dat![
2098 abox!((), "This is a 3-tuple with a comment."),
2099 12u8,
2100 13u8,
2101 ],
2102 },
2103 listdat![
2104 abox!((), "A line comment"),
2105 8u8,
2106 9u8,
2107 ],
2108 ];
2109 let expected = vec![
2110 "[",
2111 " 1,",
2112 " \"two\",",
2113 " (omap|{",
2114 " ! Ordered maps are a great way to fix the order of a map,",
2115 " ! allowing, for example, you to position multiline comments",
2116 " ! where you want them.",
2117 " 3: [",
2118 " 4,",
2119 " \"five\",",
2120 " (ipv4|(b4|[1, 2, 3, 4])),",
2121 " 6",
2122 " ],",
2123 " 11: (t3|[",
2124 " ! This is a 3-tuple with a comment.",
2125 " 12,",
2126 " 13",
2127 " ])",
2128 " }),",
2129 " [",
2130 " ! A line comment",
2131 " 8,",
2132 " 9",
2133 " ]",
2134 "]",
2135 ];
2136 test!("{}", d1);
2137 let jdat_str = res!(d1.display_some_to_lines(" "));
2138 let mut dec_cfg = DecoderConfig::default();
2139 dec_cfg.ukinds_opt = Some(ukinds);
2140 let d2 = res!(Dat::decode_string_with_config(jdat_str.clone(), &dec_cfg));
2141 let lines: Vec<&str> = jdat_str.lines().collect();
2142 test!("Display output:");
2143 for (i, line) in lines.iter().enumerate() {
2144 test!("{:03}: {}", i + 1, line);
2145 }
2146 test!("Expected output:");
2147 for (i, line) in expected.iter().enumerate() {
2148 test!("{:03}: {}", i + 1, line);
2149 }
2150 req!(lines.len(), expected.len(), "(L: actual len, R: expected len)");
2151 let mut c = 0;
2152 for line in lines {
2153 req!(line, expected[c].to_string(), "(L: encoded, R: expected) line {}", c + 1);
2154 c += 1;
2155 }
2156 let result2 = res!(d2.display_to_lines(" "));
2157 let lines: Vec<&str> = result2.split("\n").collect();
2158 test!("Display output:");
2159 for line in &lines {
2160 test!("{}", line);
2161 }
2162 req!(d1, d2, "(L: encoded, R: decoded)");
2163 Ok(())
2164 }));
2165
2166 res!(test_it(filter, &["Annotated Box debug encode decode 000", "all", "abox", "list"], || {
2167 let d0 = Dat::ABox(
2168 NoteConfig::default(),
2169 Box::new(dat!(2u8)),
2170 fmt!("This is a comment"),
2171 );
2172 let d1 = Dat::ABox(
2173 NoteConfig::default(),
2174 Box::new(Dat::Empty),
2175 fmt!("A standalone comment"),
2176 );
2177 let d5 = listdat![1u8, d0, 3u8, d1];
2178 let d5_str = fmt!("{:?}", d5);
2179 test!("List debug with comment:");
2180 for line in str!(d5_str.clone()).to_lines(" ") {
2181 test!("{}", line);
2182 }
2183 let d10 = res!(Dat::decode_string(d5_str));
2184 req!(d5, d10);
2185 Ok(())
2186 }));
2187
2188 res!(test_it(filter, &["Annotated Box debug encode decode 005", "all", "abox", "list"], || {
2189 let d0 = Dat::ABox(
2190 NoteConfig::default(),
2191 Box::new(dat!(2u8)),
2192 fmt!("This is a comment"),
2193 );
2194 let d1 = Dat::ABox(
2195 NoteConfig::default(),
2196 Box::new(Dat::Empty),
2197 fmt!("A standalone comment"),
2198 );
2199 let d5 = listdat![1u8, d0, 3u8, d1, 4u8];
2200 let d5_str = fmt!("{:?}", d5);
2201 test!("List debug with comment:");
2202 for line in str!(d5_str.clone()).to_lines(" ") {
2203 test!("{}", line);
2204 }
2205 let d10 = res!(Dat::decode_string(d5_str));
2206 req!(d5, d10);
2207 Ok(())
2208 }));
2209
2210
2211 res!(test_it(filter, &["String encode decode 140", "all", "opt", "json"], || {
2212 // An absent option must encode as JSON's own `null`, not as the JDAT
2213 // keyword `none` in quotes. A JSON reader given the string "none" sees
2214 // a present value whose content is a word; in JavaScript that string is
2215 // truthy, so a `if (x.field)` guard takes the wrong branch for a field
2216 // that is not there.
2217 let json_enc = EncoderConfig::<(), ()>::json(None);
2218 let jdat_enc = EncoderConfig::<(), ()>::jdat(None);
2219 let d1 = Dat::Opt(Box::new(None));
2220 let json_str = res!(d1.encode_string_with_config(&json_enc));
2221 req!(json_str, "null".to_string());
2222 // A present option is unaffected.
2223 let d2 = Dat::Opt(Box::new(Some(dat!(7u8))));
2224 req!(res!(d2.encode_string_with_config(&json_enc)), "7".to_string());
2225 // JDAT output is untouched: `none` is its keyword and round-trips.
2226 let jdat_str = res!(d1.encode_string_with_config(&jdat_enc));
2227 req!(jdat_str.contains("none"), true, "(jdat should still say none)");
2228 Ok(())
2229 }));
2230
2231 Ok(())
2232}