1#![forbid(unsafe_code)]
178
179use std::borrow::Cow;
180
181mod visitor;
182use visitor::{
183 ApplicationLiteralsVisitor, ArrayElementVisitor, ProcessResult, TagVisitor, Visitor,
184};
185
186pub mod application;
187pub mod error;
188mod float;
189mod space;
190mod transform;
191mod transformable;
192use space::{Comment, SDetails, MS, MSC, S, SOC};
193pub use transform::Transformation;
194pub use transformable::Transformable;
195mod number;
196use number::{Number, NumberParts, NumberValue, Sign};
197mod string;
198use string::{CborString, PreprocessedStringComponent, String1e};
199
200#[cfg(test)]
201mod tests;
202
203use error::*;
204
205const U8MAX: u64 = u8::MAX as _;
206const U16MAX: u64 = u16::MAX as _;
207const U32MAX: u64 = u32::MAX as _;
208
209#[derive(Debug, Clone, PartialEq)]
245pub struct StandaloneItem<'a>(S<'a>, Item<'a>, S<'a>);
246
247#[derive(Debug, Clone, PartialEq)]
272pub struct Item<'a>(InnerItem<'a>);
273
274impl<'a> StandaloneItem<'a> {
276 pub fn parse(s: &'a str) -> Result<Self, ParseError> {
282 cbordiagnostic::one_item(s).map_err(ParseError)
283 }
284
285 pub fn serialize(&self) -> String {
287 Unparse::serialize(self)
288 }
289
290 pub fn from_cbor(cbor: &[u8]) -> Result<Self, CborError> {
294 Ok(Self(S::default(), Item::from_cbor(cbor)?, S::default()))
295 }
296
297 pub fn from_cbor_with_rest(cbor: &[u8]) -> Result<(Self, &[u8]), CborError> {
301 let (item, rest) = Item::from_cbor_with_rest(cbor)?;
302 Ok((Self(S::default(), item, S::default()), rest))
303 }
304
305 pub fn from_cbor_possibly_incomplete(cbor: &[u8]) -> Result<Self, CborError> {
318 let (item, rest) = Item::from_cbor_with_rest_possibly_erroneous(cbor)?;
319 match rest {
320 Err(e) => {
321 if !e.is_out_of_data() {
322 return Err(e);
323 }
324 }
325 Ok(rest) => {
326 if !rest.is_empty() {
327 return Err(CborError::invalid("Data after item"));
328 };
329 }
330 }
331 Ok(Self(S::default(), item, S::default()))
332 }
333
334 pub fn to_cbor(&self) -> Result<Vec<u8>, InconsistentEdn> {
336 Ok(Unparse::to_cbor(self)?.collect())
337 }
338}
339
340impl<'a> StandaloneItem<'a> {
342 pub fn into_item(self) -> Item<'a> {
344 self.1
345 }
346
347 pub fn item(&self) -> &Item<'a> {
349 &self.1
350 }
351
352 pub fn item_mut(&mut self) -> &mut Item<'a> {
354 &mut self.1
355 }
356
357 fn inner(&self) -> &InnerItem<'a> {
358 self.1.inner()
359 }
360
361 pub fn cloned<'any>(&self) -> StandaloneItem<'any> {
364 StandaloneItem(self.0.cloned(), self.1.cloned(), self.2.cloned())
365 }
366}
367
368impl<'a> Item<'a> {
374 pub fn serialize(&self) -> String {
376 Unparse::serialize(self)
377 }
378
379 pub fn from_cbor(cbor: &[u8]) -> Result<Self, CborError> {
383 match Self::from_cbor_with_rest(cbor) {
384 Ok((s, &[])) => Ok(s),
385 Ok(_) => Err(CborError::invalid("Data after item")),
386 Err(e) => Err(e),
387 }
388 }
389
390 pub fn from_cbor_with_rest(cbor: &[u8]) -> Result<(Self, &[u8]), CborError> {
394 match Self::from_cbor_with_rest_possibly_erroneous(cbor) {
395 Err(e) => Err(e),
396 Ok((_, Err(e))) => Err(e),
397 Ok((s, Ok(rest))) => Ok((s, rest)),
398 }
399 }
400
401 fn from_cbor_with_rest_possibly_erroneous(
409 cbor: &[u8],
410 ) -> Result<(Self, Result<&[u8], CborError>), CborError> {
411 let (major, argument, spec, tail) = process_cbor_major_argument(cbor)?;
412
413 let mut return_tail = Ok(tail);
414
415 let mut s = match (major, argument, spec) {
416 (Major::Unsigned, Some(argument), spec) => Self::new_integer_decimal_with_spec(
417 argument,
418 spec.or_none_if_default_for_arg(argument),
419 ),
420 (Major::Negative, Some(argument), spec) => Self::new_integer_decimal_with_spec(
421 -1i128 - i128::from(argument),
422 spec.or_none_if_default_for_arg(argument),
423 ),
424 (Major::FloatSimple, Some(n @ 0..=19), Spec::S_i) => {
425 Simple::Numeric(Box::new(Self::new_integer_decimal(n).into())).into()
426 }
427 (Major::FloatSimple, Some(20), Spec::S_i) => Simple::False.into(),
428 (Major::FloatSimple, Some(21), Spec::S_i) => Simple::True.into(),
429 (Major::FloatSimple, Some(22), Spec::S_i) => Simple::Null.into(),
430 (Major::FloatSimple, Some(23), Spec::S_i) => Simple::Undefined.into(),
431 (Major::FloatSimple, Some(n @ 32..=255), Spec::S_0) => {
432 Simple::Numeric(Box::new(Self::new_integer_decimal(n).into())).into()
433 }
434 (Major::FloatSimple, _, Spec::S_i | Spec::S_0) => {
436 return Err(CborError::invalid(
437 "erroneous representation of simple value",
438 ))
439 }
440 (Major::FloatSimple, Some(0x7c00), Spec::S_1) => {
441 Number(Cow::from("Infinity")).with_spec(Some(Spec::S_1))
442 }
443 (Major::FloatSimple, Some(0xfc00), Spec::S_1) => {
444 Number(Cow::from("-Infinity")).with_spec(Some(Spec::S_1))
445 }
446 (Major::FloatSimple, Some(0x7e00), Spec::S_1) => {
447 Number(Cow::from("NaN")).with_spec(Some(Spec::S_1))
448 }
449 (Major::FloatSimple, Some(n), Spec::S_1) => {
450 let f =
451 float::f16_bits_to_f64(n.try_into().expect("Range limited by construction"));
452 Number::new_float(f).with_spec(Some(Spec::S_1))
453 }
454 (Major::FloatSimple, Some(n), Spec::S_2) => {
455 let n: u32 = n.try_into().expect("Range limited by construction");
456 let f = f64::from(f32::from_bits(n));
457 Number::new_float(f).with_spec(Some(Spec::S_2))
458 }
459 (Major::FloatSimple, Some(n), Spec::S_3) => {
460 let f = f64::from_bits(n);
461 Number::new_float(f).with_spec(Some(Spec::S_3))
462 }
463 (Major::FloatSimple, None, _ )
464 | (Major::FloatSimple, _ , Spec::S_) => {
465 return Err(CborError::invalid(
466 "Break code only expected at end of indefinte length items",
467 ))
468 }
469 (Major::Tagged, Some(n), s) => {
470 let (item, new_tail) = StandaloneItem::from_cbor_with_rest(tail)?;
472 return_tail = Ok(new_tail);
473 item.tagged_with_spec(n, s.or_none_if_default_for_arg(n))
474 }
475 (Major::Unsigned | Major::Negative | Major::Tagged, None, _) => {
476 return Err(CborError::invalid(
477 "Integer/Tag with indefinite length encoding is not well-formed",
478 ))
479 }
480 (Major::ByteString, Some(n), spec) => {
481 let data = n.try_into().ok().and_then(|n| tail.get(..n));
482 match data {
483 Some(d) => {
484 return_tail = Ok(&tail[d.len()..]);
485 Self::new_bytes_hex_with_spec(d, spec.or_none_if_default_for_arg(n))
486 }
487 None => {
488 let error = CborError::out_of_data("Announced bytes unavailable");
489 let ellipsis = Item::error_ellipsis(&error);
490 return_tail = Err(error);
491 let mut item =
492 Self::new_bytes_hex_with_spec(tail, spec.or_none_if_default_for_arg(n));
493 item.push_string_concatenation(ellipsis);
494 item
495 }
496 }
497 }
498 (Major::TextString, Some(n), spec) => {
499 let data = n.try_into().ok().and_then(|n| tail.get(..n));
500 match data {
501 Some(d) => {
502 let data = core::str::from_utf8(d)
503 .map_err(|_| CborError::invalid("Text string must be valid UTF-8"))?;
504 return_tail = Ok(&tail[data.len()..]);
505 Self::new_text_with_spec(data, spec.or_none_if_default_for_arg(n))
506 }
507 None => {
508 let error =
509 CborError::out_of_data("Announced bytes unavailable in text string");
510 let ellipsis = Item::error_ellipsis(&error);
511 return_tail = Err(error);
512
513 let tail_str = match core::str::from_utf8(tail) {
514 Ok(d) => d,
515 Err(e) => core::str::from_utf8(&tail[..e.valid_up_to()]).unwrap(),
516 };
517 let mut item =
518 Self::new_text_with_spec(tail_str, spec.or_none_if_default_for_arg(n));
519 item.push_string_concatenation(ellipsis);
520 item
521 }
522 }
523 }
524 (
527 Major::ByteString | Major::TextString,
528 None,
529 _, ) => {
531 let mut items = vec![];
532 while return_tail.as_ref().is_ok_and(|t| t.first() != Some(&0xff)) {
533 let (inner_major, argument, spec, new_tail) =
534 process_cbor_major_argument(return_tail.unwrap())?;
535 let Some(argument) = argument.and_then(|a| usize::try_from(a).ok()) else {
536 return Err(CborError::invalid(
539 "Indefinite length strings can only contain definite lengths and must fit in data",
540 ));
541 };
542 if inner_major != major {
543 return Err(CborError::invalid(
544 "Indefinite length strings can only contain matching items",
545 ));
546 }
547 if new_tail.len() < argument {
548 return Err(CborError::out_of_data(
549 "Announced bytes unavailable inside indefinite length byte string",
550 ));
551 }
552 let (item_data, new_tail) = new_tail.split_at(argument);
554 return_tail = Ok(new_tail);
555 items.push(match major {
556 Major::ByteString => {
557 CborString::new_bytes_hex_with_spec(item_data, Some(spec))
558 }
559 Major::TextString => CborString::new_text_with_spec(
560 core::str::from_utf8(item_data).map_err(|_| {
561 CborError::invalid("Text string must be valid UTF-8")
562 })?,
563 Some(spec),
564 ),
565 _ => unreachable!(),
566 });
567 }
568 if return_tail.as_ref().unwrap().is_empty() {
569 return Err(CborError::out_of_data(
570 "Indefinite length byte string terminated after item",
571 ));
572 }
573 return_tail = Ok(&return_tail.as_ref().unwrap()[1..]);
574
575 let mut items = items.drain(..);
576 if let Some(first_item) = items.next() {
577 InnerItem::StreamString(
578 Default::default(),
579 NonemptyMscVec::new(first_item, items),
580 )
581 .into()
582 } else {
583 todo!()
584 }
585 }
586 (Major::Array, mut length, spec) => {
587 let mut items = vec![];
589 let spec = match length {
590 Some(l) => spec.or_none_if_default_for_arg(l),
591 None => Some(spec), };
593 while length != Some(0)
594 && return_tail.as_ref().is_ok_and(|t| t.first() != Some(&0xff))
595 {
596 match Self::from_cbor_with_rest_possibly_erroneous(return_tail.unwrap()) {
597 Ok((item, Ok(new_tail))) => {
598 items.push(item);
599 return_tail = Ok(new_tail);
600 }
601 Ok((item, Err(e))) => {
602 items.push(item);
603 return_tail = Err(e);
604 }
605 Err(e) => {
606 return_tail = Err(e);
607 break;
613 }
614 };
615 if let Some(ref mut n) = &mut length {
616 *n -= 1;
617 }
618 }
619 if length.is_none() {
620 if let Ok(t) = return_tail.as_ref() {
621 if t.is_empty() {
622 return_tail = Err(CborError::out_of_data(
623 "Indefinite length array terminated after item",
624 ));
625 } else {
626 return_tail = Ok(&t[1..]);
627 }
628 }
629 }
630 if let Err(e) = &return_tail {
631 if length != Some(0) {
632 items.push(Item::error_ellipsis(e));
633 }
634 }
635 InnerItem::Array(SpecMscVec::new(spec, items.into_iter())).into()
636 }
637 (Major::Map, mut length, spec) => {
638 let mut items = vec![];
640 let spec = match length {
641 Some(l) => spec.or_none_if_default_for_arg(l),
642 None => Some(spec), };
644 while length != Some(0)
645 && return_tail.as_ref().is_ok_and(|t| t.first() != Some(&0xff))
646 {
647 let (key, new_tail) =
648 match Self::from_cbor_with_rest_possibly_erroneous(return_tail.unwrap()) {
649 Ok(knt) => knt,
650 Err(e) => {
651 return_tail = Err(e);
654 break;
655 }
656 };
657 let (value, new_tail) = match new_tail {
658 Ok(t) => match Self::from_cbor_with_rest_possibly_erroneous(t) {
659 Ok(vnt) => vnt,
661 Err(e) => (Item::error_ellipsis(&e), Err(e)),
663 },
664 Err(e) => (Item::error_ellipsis(&e), Err(e)),
668 };
669 return_tail = new_tail;
670 items.push(Kp::new(key, value));
671 if let Some(ref mut n) = &mut length {
672 *n -= 1;
673 }
674 }
675 if length.is_none() {
676 if let Ok(t) = return_tail.as_ref() {
677 if t.is_empty() {
678 return_tail = Err(CborError::out_of_data(
679 "Indefinite length map terminated after item",
680 ));
681 } else {
682 return_tail = Ok(&t[1..]);
683 }
684 }
685 }
686 if let Err(e) = &return_tail {
687 if length != Some(0) {
688 items.push(Kp::new(Item::error_ellipsis(e), Item::error_ellipsis(e)));
689 }
690 }
691 InnerItem::Map(SpecMscVec::new(spec, items.into_iter())).into()
692 }
693 };
694
695 s.set_delimiters(DelimiterPolicy::SingleLineRegularSpacing);
696 Ok((s, return_tail))
697 }
698
699 fn visit(&mut self, visitor: &mut impl Visitor<'a>) -> ProcessResult {
700 let mut result = visitor.process(self);
701 if result.take_recurse() {
702 self.0.visit(visitor);
703 }
704 result
705 }
706
707 pub fn cloned<'any>(&self) -> Item<'any> {
710 Item(self.0.cloned())
711 }
712}
713
714impl<'a> Item<'a> {
716 fn inner(&self) -> &InnerItem<'a> {
717 &self.0
718 }
719
720 fn inner_mut(&mut self) -> &mut InnerItem<'a> {
721 &mut self.0
722 }
723}
724
725impl<'a> StandaloneItem<'a> {
727 fn tagged_with_spec(self, tag: u64, spec: Option<Spec>) -> Item<'a> {
728 InnerItem::Tagged(tag, spec, Box::new(self)).into()
729 }
730
731 pub fn tagged(self, tag: u64) -> Item<'a> {
733 InnerItem::Tagged(tag, None, Box::new(self)).into()
734 }
735}
736
737impl<'a> Item<'a> {
739 fn new_integer_decimal_with_spec(value: impl Into<i128>, spec: Option<Spec>) -> Self {
740 Number(format!("{}", value.into()).into()).with_spec(spec)
741 }
742
743 pub fn new_integer_decimal(value: impl Into<i128>) -> Self {
747 Self::new_integer_decimal_with_spec(value, None)
748 }
749
750 pub fn new_float_decimal(value: f64) -> Self {
752 Number::new_float(value).with_spec(None)
753 }
754
755 pub fn new_integer_hex(value: impl Into<u64>) -> Self {
759 InnerItem::Number(Number(format!("0x{:x}", value.into()).into()), None).into()
760 }
761
762 fn new_bytes_hex_with_spec(value: &[u8], spec: Option<Spec>) -> Self {
763 InnerItem::String(CborString::new_bytes_hex_with_spec(value, spec)).into()
764 }
765
766 pub fn new_bytes_hex(value: &[u8]) -> Self {
769 Self::new_bytes_hex_with_spec(value, None)
770 }
771
772 fn new_text_with_spec(value: &str, spec: Option<Spec>) -> Self {
773 InnerItem::String(CborString::new_text_with_spec(value, spec)).into()
774 }
775
776 pub fn new_text(value: &str) -> Self {
787 Self::new_text_with_spec(value, None)
788 }
789
790 pub fn new_application_literal(identifier: &str, value: &str) -> Result<Self, InconsistentEdn> {
791 if cbordiagnostic::app_prefix(identifier).is_err() {
792 return Err(InconsistentEdn(
794 "Identifier is not a valid application string identifier",
795 ));
796 };
797 Ok(InnerItem::String(CborString::new_application_literal(identifier, value, None)).into())
798 }
799
800 pub fn new_array(items: impl Iterator<Item = Item<'a>>) -> Self {
802 InnerItem::Array(SpecMscVec::new(None, items)).into()
803 }
804
805 pub fn new_map(items: impl Iterator<Item = (Item<'a>, Item<'a>)>) -> Self {
807 InnerItem::Map(SpecMscVec::new(
808 None,
809 items.map(|(key, value)| Kp::new(key, value)),
810 ))
811 .into()
812 }
813
814 pub fn tagged(self, tag: u64) -> Item<'a> {
816 StandaloneItem::from(self).tagged(tag)
817 }
818
819 fn error_ellipsis(_error: &CborError) -> Self {
825 Self(InnerItem::String(CborString {
826 items: vec![string::String1e::Ellipsis(3)],
827 separators: Vec::new(),
828 }))
829 }
830
831 fn push_string_concatenation(&mut self, next: Item<'a>) {
837 let next = match next.0 {
838 InnerItem::String(cs) => cs,
839 _ => panic!("string-concatenating something that is not a string"),
840 };
841 let inner = match &mut self.0 {
842 InnerItem::String(cs) => cs,
843 _ => panic!("string-concatenating onto something that is not a string"),
844 };
845 inner.items.extend(next.items);
846 inner
847 .separators
848 .push((Default::default(), Default::default()));
849 inner.separators.extend(next.separators);
850 }
851}
852
853impl StandaloneItem<'_> {
857 pub fn with_comment(self, comment: &str) -> Self {
859 let wrapped_comment = if comment.contains('/') {
860 format!("# {}\n", comment.replace('\n', "\n# "))
861 } else {
862 format!("/ {} /", comment)
863 };
864 Self(S(wrapped_comment.into()), self.1, self.2)
865 }
866
867 pub fn set_comment(&mut self, comment: &str) {
869 let wrapped_comment = if comment.contains('/') {
870 format!("# {}\n", comment.replace('\n', "\n# "))
871 } else {
872 format!("/ {} /", comment)
873 };
874 self.0 = S(wrapped_comment.into());
875 }
876}
877
878impl<'a> Item<'a> {
880 pub fn get_application_literal(&self) -> Result<(String, String), TypeMismatch> {
884 let InnerItem::String(CborString { ref items, .. }) = self.inner() else {
885 return Err(TypeMismatch::expecting("application-oriented literal"));
886 };
887 let [chunk] = items.as_slice() else {
888 return Err(TypeMismatch::expecting(
889 "single application-oriented literal",
890 ));
891 };
892 let PreprocessedStringComponent::AppString(identifier, value) = chunk
893 .preprocess()
894 .map_err(|_| TypeMismatch::expecting("application-oriented literal"))?
897 else {
898 return Err(TypeMismatch::expecting("application-oriented literal"));
899 };
900
901 Ok((identifier, value))
902 }
903
904 pub fn get_bytes(&self) -> Result<Vec<u8>, TypeMismatch> {
910 let mut result = vec![];
911
912 let mut append_items = |items: &Vec<String1e>| -> Result<(), TypeMismatch> {
913 for item in items {
914 if item
915 .encoded_major_type()
916 .map_err(|_| TypeMismatch::expecting("encodable item"))?
917 != Major::ByteString
918 {
919 return Err(TypeMismatch::expecting("byte literal"));
920 }
921 result.extend(
922 item.bytes_value()
923 .map_err(|_| TypeMismatch::expecting("byte literal or compatible"))?,
924 );
925 }
926 Ok(())
927 };
928
929 match self.inner() {
930 InnerItem::String(CborString { ref items, .. }) => append_items(items)?,
931 InnerItem::StreamString(_, ref chunks) => {
932 for CborString { ref items, .. } in chunks.iter() {
933 append_items(items)?;
934 }
935 }
936 _ => return Err(TypeMismatch::expecting("byte literal")),
937 }
938
939 Ok(result)
940 }
941
942 pub fn get_string(&self) -> Result<String, TypeMismatch> {
956 let mut result = vec![];
957
958 let mut append_items = |items: &Vec<String1e>| -> Result<(), TypeMismatch> {
959 for item in items {
960 result.extend(
961 item.bytes_value()
962 .map_err(|_| TypeMismatch::expecting("text literal or compatible"))?,
963 );
964 }
965 Ok(())
966 };
967
968 let check_first = |item: &String1e<'_>| -> Result<(), TypeMismatch> {
972 if item
973 .encoded_major_type()
974 .map_err(|_| TypeMismatch::expecting("encodable item"))?
975 != Major::TextString
976 {
977 return Err(TypeMismatch::expecting("text literal"));
978 }
979 Ok(())
980 };
981
982 match self.inner() {
983 InnerItem::String(CborString { ref items, .. }) => {
984 check_first(items.first().expect("Part of the type guarantees"))?;
985 append_items(items)?;
986 }
987 InnerItem::StreamString(_, ref chunks) => {
988 check_first(
989 chunks
990 .first
991 .items
992 .first()
993 .expect("Part of the type guarantees"),
994 )?;
995 for CborString { ref items, .. } in chunks.iter() {
996 append_items(items)?;
997 }
998 }
999 _ => return Err(TypeMismatch::expecting("byte literal")),
1000 }
1001
1002 String::from_utf8(result).map_err(|_| TypeMismatch::expecting("valid UTF-8"))
1003 }
1004
1005 pub fn get_tag(&self) -> Result<u64, TypeMismatch> {
1010 let InnerItem::Tagged(tag, _, _) = self.inner() else {
1011 return Err(TypeMismatch::expecting("tagged item"));
1012 };
1013 Ok(*tag)
1014 }
1015
1016 pub fn get_tagged(&self) -> Result<&StandaloneItem<'a>, TypeMismatch> {
1021 let InnerItem::Tagged(_, _, ref item) = self.inner() else {
1022 return Err(TypeMismatch::expecting("tagged item"));
1023 };
1024 Ok(item)
1025 }
1026
1027 pub fn get_tagged_mut(&mut self) -> Result<&mut StandaloneItem<'a>, TypeMismatch> {
1032 let InnerItem::Tagged(_, _, ref mut item) = self.inner_mut() else {
1033 return Err(TypeMismatch::expecting("tagged item"));
1034 };
1035 Ok(item)
1036 }
1037
1038 pub fn get_integer(&self) -> Result<i128, TypeMismatch> {
1043 let InnerItem::Number(ref number, _) = self.inner() else {
1044 return Err(TypeMismatch::expecting("integer"));
1045 };
1046 match number.value() {
1047 NumberValue::Float(_) => Err(TypeMismatch::expecting("integer")),
1048 NumberValue::Positive(n) => Ok(n.into()),
1049 NumberValue::Negative(n) => Ok(-1 - i128::from(n)),
1050 NumberValue::Big(n) => n
1052 .try_into()
1053 .map_err(|_| TypeMismatch::expecting("integer in i128 range")),
1054 }
1055 }
1056
1057 pub fn get_float(&self) -> Result<f64, TypeMismatch> {
1061 let InnerItem::Number(ref number, _) = self.inner() else {
1062 return Err(TypeMismatch::expecting("float"));
1063 };
1064 match number.value() {
1065 NumberValue::Float(f) => Ok(f),
1066 NumberValue::Positive(_) => Err(TypeMismatch::expecting("float (not integer)")),
1067 NumberValue::Negative(_) => Err(TypeMismatch::expecting("float (not integer)")),
1068 NumberValue::Big(_) => Err(TypeMismatch::expecting("float (not integer)")),
1069 }
1070 }
1071
1072 pub fn get_array_items(&self) -> Result<impl Iterator<Item = &Item<'a>>, TypeMismatch> {
1076 let InnerItem::Array(smv) = self.inner() else {
1077 return Err(TypeMismatch::expecting("array"));
1078 };
1079
1080 Ok(smv.iter())
1081 }
1082
1083 pub fn get_array_items_mut(
1087 &mut self,
1088 ) -> Result<impl Iterator<Item = &mut Item<'a>>, TypeMismatch> {
1089 let InnerItem::Array(smv) = self.inner_mut() else {
1090 return Err(TypeMismatch::expecting("array"));
1091 };
1092
1093 Ok(smv.iter_mut())
1094 }
1095
1096 pub fn get_map_items(
1100 &self,
1101 ) -> Result<impl Iterator<Item = (&Item<'a>, &Item<'a>)>, TypeMismatch> {
1102 let InnerItem::Map(smv) = self.inner() else {
1103 return Err(TypeMismatch::expecting("map"));
1104 };
1105
1106 Ok(smv.iter().map(|kp| (&kp.key, &kp.value)))
1107 }
1108
1109 pub fn get_map_items_mut(
1113 &mut self,
1114 ) -> Result<impl Iterator<Item = (&mut Item<'a>, &mut Item<'a>)>, TypeMismatch> {
1115 let InnerItem::Map(smv) = self.inner_mut() else {
1116 return Err(TypeMismatch::expecting("map"));
1117 };
1118
1119 Ok(smv.iter_mut().map(|kp| (&mut kp.key, &mut kp.value)))
1120 }
1121
1122 pub fn discard_encoding_indicators(&mut self) {
1128 self.inner_mut().discard_encoding_indicators();
1129 }
1130
1131 pub fn set_delimiters(&mut self, policy: DelimiterPolicy) {
1137 self.0.set_delimiters(policy);
1138 }
1139
1140 pub fn with_comment(self, comment: &str) -> StandaloneItem<'a> {
1142 let wrapped_comment = if comment.contains('/') {
1143 format!("# {}\n", comment.replace('\n', "\n# "))
1144 } else {
1145 format!("/ {} /", comment)
1146 };
1147 StandaloneItem(S(wrapped_comment.into()), self, S::default())
1148 }
1149
1150 pub fn visit_map_elements<F>(&mut self, f: &mut F) -> Result<(), TypeMismatch>
1167 where
1168 F: FnMut(
1169 &mut Item<'a>,
1170 &mut Item<'a>,
1171 ) -> Result<(Option<String>, Result<Option<String>, String>), String>
1172 + ?Sized,
1173 {
1174 use crate::space::Spaceish;
1175
1176 let InnerItem::Map(map) = &mut self.0 else {
1177 return Err(TypeMismatch::expecting("map"));
1178 };
1179 let SpecMscVec::Present {
1180 spec: _,
1181 s: first_space,
1182 items,
1183 } = map
1184 else {
1185 return Ok(());
1187 };
1188 let mut tail = items.tail.iter_mut().peekable();
1189
1190 let _space_before_key = first_space;
1192 let key = &mut items.first.key;
1193 let space_after_key = &mut items.first.s0;
1194 let _space_before_value = &mut items.first.s1;
1196 let value = &mut items.first.value;
1197 let space_after_value = tail
1198 .peek_mut()
1199 .map(|i| &mut i.0 as &mut dyn Spaceish)
1200 .unwrap_or(&mut items.soc);
1201
1202 let (key_comment, value_comment) = match f(key, value) {
1204 Ok(r) => r,
1205 Err(e) => (Some(e), Ok(None)),
1206 };
1207 let value_comment = match value_comment {
1208 Ok(s) => s,
1209 Err(s) => Some(s),
1210 };
1211 if let Some(key_comment) = key_comment {
1212 space_after_key.prepend_comment(&key_comment)
1213 }
1214 if let Some(value_comment) = value_comment {
1215 space_after_value.prepend_comment(&value_comment)
1216 }
1217
1218 while let Some((msc, next)) = tail.next() {
1219 let _space_before_key = msc;
1221 let key = &mut next.key;
1222 let space_after_key = &mut next.s0;
1223 let _space_before_value = &mut items.first.s1;
1225 let value = &mut next.value;
1226 let space_after_value = tail
1227 .peek_mut()
1228 .map(|i| &mut i.0 as &mut dyn Spaceish)
1229 .unwrap_or(&mut items.soc);
1230
1231 let (key_comment, value_comment) = match f(key, value) {
1233 Ok(r) => r,
1234 Err(e) => (Some(e), Ok(None)),
1235 };
1236 let value_comment = match value_comment {
1237 Ok(s) => s,
1238 Err(s) => Some(s),
1239 };
1240 if let Some(key_comment) = key_comment {
1241 space_after_key.prepend_comment(&key_comment)
1242 }
1243 if let Some(value_comment) = value_comment {
1244 space_after_value.prepend_comment(&value_comment)
1245 }
1246 }
1247
1248 Ok(())
1249 }
1250
1251 pub fn visit_array_elements<F>(&mut self, f: &mut F) -> Result<(), TypeMismatch>
1274 where
1275 F: FnMut(&mut Item<'a>) -> Result<Option<String>, String> + ?Sized,
1276 {
1277 if !matches!(self.0, InnerItem::Array(_)) {
1278 return Err(TypeMismatch::expecting("array"));
1279 }
1280 self.visit(&mut ArrayElementVisitor::new(f)).done();
1281 Ok(())
1282 }
1283}
1284
1285impl Unparse for StandaloneItem<'_> {
1286 fn serialize_write(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
1287 self.0.serialize_write(formatter)?;
1288 self.1.serialize_write(formatter)?;
1289 self.2.serialize_write(formatter)?;
1290 Ok(())
1291 }
1292
1293 fn to_cbor(&self) -> Result<impl Iterator<Item = u8>, InconsistentEdn> {
1294 self.1.to_cbor()
1295 }
1296}
1297
1298impl Unparse for Item<'_> {
1299 fn serialize_write(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
1300 self.0.serialize_write(formatter)
1301 }
1302
1303 fn to_cbor(&self) -> Result<impl Iterator<Item = u8>, InconsistentEdn> {
1304 self.0.to_cbor()
1305 }
1306}
1307
1308impl<'a> From<InnerItem<'a>> for StandaloneItem<'a> {
1309 fn from(inner: InnerItem<'a>) -> Self {
1310 Item::from(inner).into()
1311 }
1312}
1313
1314impl<'a> From<Item<'a>> for StandaloneItem<'a> {
1315 fn from(inner: Item<'a>) -> Self {
1316 Self(S::default(), inner, S::default())
1317 }
1318}
1319
1320impl<'a> From<InnerItem<'a>> for Item<'a> {
1321 fn from(inner: InnerItem<'a>) -> Self {
1322 Item(inner)
1323 }
1324}
1325
1326#[derive(Debug, Clone, PartialEq)]
1341pub struct Sequence<'a> {
1342 s0: S<'a>,
1343 items: Option<NonemptyMscVec<'a, Item<'a>>>,
1344}
1345
1346impl<'a> Sequence<'a> {
1347 pub fn parse(s: &'a str) -> Result<Self, ParseError> {
1353 cbordiagnostic::seq(s).map_err(ParseError)
1354 }
1355
1356 pub fn serialize(&self) -> String {
1358 Unparse::serialize(self)
1359 }
1360
1361 pub fn from_cbor(cbor: &[u8]) -> Result<Self, CborError> {
1362 let mut tail = cbor;
1363 let mut items = vec![];
1366 while !tail.is_empty() {
1367 let (item, new_tail) = Item::from_cbor_with_rest(tail)?;
1368 items.push(item);
1369 tail = new_tail;
1370 }
1371 let mut s = Self::new(items.into_iter());
1372 s.set_delimiters(DelimiterPolicy::SingleLineRegularSpacing);
1373 Ok(s)
1374 }
1375
1376 pub fn from_cbor_possibly_incomplete(cbor: &[u8]) -> Result<Self, CborError> {
1389 let mut tail = cbor;
1390 let mut items = vec![];
1391 while !tail.is_empty() {
1392 let (item, new_tail) = Item::from_cbor_with_rest_possibly_erroneous(tail)?;
1393 items.push(item);
1394 match new_tail {
1395 Ok(t) => tail = t,
1396 Err(e) => {
1397 if e.is_out_of_data() {
1398 items.push(Item::error_ellipsis(&e));
1400 break;
1401 } else {
1402 return Err(e);
1403 }
1404 }
1405 }
1406 }
1407 let mut s = Self::new(items.into_iter());
1408 s.set_delimiters(DelimiterPolicy::SingleLineRegularSpacing);
1409 Ok(s)
1410 }
1411
1412 pub fn to_cbor(&self) -> Result<Vec<u8>, InconsistentEdn> {
1414 Ok(Unparse::to_cbor(self)?.collect())
1415 }
1416
1417 pub fn new(mut items: impl Iterator<Item = Item<'a>>) -> Self {
1419 Sequence {
1420 s0: Default::default(),
1421 items: items.next().map(|first| NonemptyMscVec::new(first, items)),
1422 }
1423 }
1424
1425 pub fn items(&self) -> impl Iterator<Item = &Item<'a>> {
1427 self.items.as_ref().map(|i| i.iter()).into_iter().flatten()
1428 }
1429
1430 pub fn items_mut(&mut self) -> impl Iterator<Item = &mut Item<'a>> {
1432 self.items
1433 .as_mut()
1434 .map(|i| i.iter_mut())
1435 .into_iter()
1436 .flatten()
1437 }
1438
1439 #[deprecated(note = "renamed to items_mut()")]
1440 pub fn get_items_mut(&mut self) -> impl Iterator<Item = &mut Item<'a>> {
1441 self.items_mut()
1442 }
1443
1444 pub fn discard_encoding_indicators(&mut self) {
1450 for i in self.items_mut() {
1451 i.discard_encoding_indicators()
1452 }
1453 }
1454
1455 pub fn cloned<'any>(&self) -> Sequence<'any> {
1458 Sequence {
1459 s0: self.s0.cloned(),
1460 items: self.items.as_ref().map(|i| i.cloned()),
1461 }
1462 }
1463}
1464
1465impl Unparse for Sequence<'_> {
1466 fn serialize_write(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
1467 self.s0.serialize_write(formatter)?;
1468 if let Some(items) = self.items.as_ref() {
1469 items.serialize_write(formatter)?;
1470 }
1471 Ok(())
1472 }
1473
1474 fn to_cbor(&self) -> Result<impl Iterator<Item = u8>, InconsistentEdn> {
1475 let chain = self.items.as_ref().map(|items| items.to_cbor());
1476 let chain = chain.transpose();
1477 chain.map(|optit| optit.into_iter().flatten())
1478 }
1479}
1480
1481#[derive(Copy, Clone, Debug, PartialEq)]
1483#[non_exhaustive]
1484pub enum DelimiterPolicy {
1485 DiscardAll,
1488 DiscardAllButComments,
1490 SingleLineRegularSpacing,
1495 IndentedRegularSpacing {
1500 base_indent: usize,
1502 indent_level: usize,
1504 max_width: usize,
1512 trailing_newline: TrailingNewlinePolicy,
1514 },
1515 SingleSpace,
1520}
1521
1522impl DelimiterPolicy {
1523 pub const fn indented() -> Self {
1525 Self::IndentedRegularSpacing {
1526 base_indent: 0,
1527 indent_level: 4,
1528 max_width: 80,
1529 trailing_newline: TrailingNewlinePolicy::IfMultiline,
1530 }
1531 }
1532
1533 pub const fn indented_with_final_newline() -> Self {
1536 Self::IndentedRegularSpacing {
1537 base_indent: 0,
1538 indent_level: 4,
1539 max_width: 80,
1540 trailing_newline: TrailingNewlinePolicy::Always,
1541 }
1542 }
1543}
1544
1545#[derive(Copy, Clone, Debug, PartialEq)]
1546pub enum TrailingNewlinePolicy {
1547 Never,
1549 IfMultiline,
1551 Always,
1553}
1554
1555trait Unparse: Sized {
1557 fn serialize_write(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result;
1561
1562 fn serialize(&self) -> String {
1567 struct Unparsed<'a, T: Unparse>(&'a T);
1568 impl<T: Unparse> core::fmt::Display for Unparsed<'_, T> {
1569 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1570 self.0.serialize_write(f)
1571 }
1572 }
1573
1574 format!("{}", Unparsed(self))
1575 }
1576
1577 fn to_cbor(&self) -> Result<impl Iterator<Item = u8>, InconsistentEdn>;
1578}
1579
1580#[derive(Debug, Clone, PartialEq)]
1586struct NonemptyMscVec<'a, T: Unparse> {
1587 first: Box<T>,
1590 tail: Vec<(MSC<'a>, T)>,
1591 soc: SOC<'a>,
1592}
1593
1594impl<'a, T: Unparse> NonemptyMscVec<'a, T> {
1595 fn new(first: T, tail: impl Iterator<Item = T>) -> Self {
1597 Self {
1598 first: Box::new(first),
1599 tail: tail.map(|i| (Default::default(), i)).collect(),
1600 soc: Default::default(),
1601 }
1602 }
1603
1604 fn new_parsing(first: T, tail: Vec<(MSC<'a>, T)>, soc: SOC<'a>) -> Self {
1606 Self {
1607 first: Box::new(first),
1608 tail,
1609 soc,
1610 }
1611 }
1612
1613 fn len(&self) -> usize {
1614 1 + self.tail.len()
1615 }
1616
1617 fn iter(&self) -> impl Iterator<Item = &T> {
1618 core::iter::once(&*self.first).chain(self.tail.iter().map(|(_msc, t)| t))
1619 }
1620}
1621
1622impl<'a> NonemptyMscVec<'a, Item<'a>> {
1623 fn visit(&mut self, visitor: &mut impl Visitor<'a>) -> ProcessResult {
1624 let mut own_result = self.first.visit(visitor);
1625 let mut last_result: Option<ProcessResult> = None;
1626 for (msc, item) in self.tail.iter_mut() {
1627 if let Some(result) = last_result.take() {
1628 result.use_space_after(msc).done();
1629 } else {
1630 own_result = own_result.use_space_after(msc);
1631 }
1632 let item_result = item.visit(visitor);
1633 let replaced = last_result.replace(item_result.use_space_before(msc));
1634 assert!(replaced.is_none());
1635 }
1636 if let Some(result) = last_result.take() {
1637 result.use_space_after(&mut self.soc).done();
1638 } else {
1639 own_result = own_result.use_space_after(&mut self.soc);
1640 }
1641
1642 own_result
1643 }
1644
1645 fn cloned<'any>(&self) -> NonemptyMscVec<'any, Item<'any>> {
1646 NonemptyMscVec {
1647 first: Box::new(self.first.cloned()),
1648 tail: self
1649 .tail
1650 .iter()
1651 .map(|(msc, i)| (msc.cloned(), i.cloned()))
1652 .collect(),
1653 soc: self.soc.cloned(),
1654 }
1655 }
1656}
1657impl<'a> NonemptyMscVec<'a, Kp<'a>> {
1660 fn visit(&mut self, visitor: &mut impl Visitor<'a>) -> ProcessResult {
1661 let mut own_result = self.first.visit(visitor);
1662 let mut last_result: Option<ProcessResult> = None;
1663 for (msc, item) in self.tail.iter_mut() {
1664 if let Some(result) = last_result.take() {
1665 result.use_space_after(msc).done();
1666 } else {
1667 own_result = own_result.use_space_after(msc);
1668 }
1669 let item_result = item.visit(visitor);
1670 let replaced = last_result.replace(item_result.use_space_before(msc));
1671 assert!(replaced.is_none());
1672 }
1673 if let Some(result) = last_result.take() {
1674 result.use_space_after(&mut self.soc).done();
1675 } else {
1676 own_result = own_result.use_space_after(&mut self.soc);
1677 }
1678
1679 own_result
1680 }
1681
1682 fn cloned<'any>(&self) -> NonemptyMscVec<'any, Kp<'any>> {
1683 NonemptyMscVec {
1684 first: Box::new(self.first.cloned()),
1685 tail: self
1686 .tail
1687 .iter()
1688 .map(|(msc, i)| (msc.cloned(), i.cloned()))
1689 .collect(),
1690 soc: self.soc.cloned(),
1691 }
1692 }
1693}
1694impl<'a> NonemptyMscVec<'a, CborString<'a>> {
1696 fn cloned<'any>(&self) -> NonemptyMscVec<'any, CborString<'any>> {
1697 NonemptyMscVec {
1698 first: Box::new(self.first.cloned()),
1699 tail: self
1700 .tail
1701 .iter()
1702 .map(|(msc, i)| (msc.cloned(), i.cloned()))
1703 .collect(),
1704 soc: self.soc.cloned(),
1705 }
1706 }
1707}
1708
1709macro_rules! nmv_concrete_impl {
1712 ($t:ident) => {
1713 impl<'a> NonemptyMscVec<'a, $t<'a>> {
1714 fn iter_mut(&mut self) -> impl Iterator<Item = &mut $t<'a>> {
1715 let first: &mut $t<'a> = &mut self.first;
1716 let tail = &mut self.tail;
1717 core::iter::once(first).chain(tail.iter_mut().map(|(_msc, i)| i))
1718 }
1719 }
1720 };
1721}
1722nmv_concrete_impl!(Item);
1723nmv_concrete_impl!(CborString);
1724
1725impl<T: Unparse> Unparse for NonemptyMscVec<'_, T> {
1726 fn serialize_write(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
1727 self.first.serialize_write(formatter)?;
1728 for (msc, item) in self.tail.iter() {
1729 msc.serialize_write(formatter)?;
1730 item.serialize_write(formatter)?;
1731 }
1732 self.soc.serialize_write(formatter)?;
1733 Ok(())
1734 }
1735
1736 fn to_cbor(&self) -> Result<impl Iterator<Item = u8>, InconsistentEdn> {
1737 let collected: Result<Vec<_>, _> = self.iter().map(Unparse::to_cbor).collect();
1739 Ok(collected?.into_iter().flatten())
1740 }
1741}
1742
1743#[derive(Debug, Clone, PartialEq)]
1750enum SpecMscVec<'a, T: Unparse> {
1751 Present {
1752 spec: Option<(Spec, MS<'a>)>,
1753 s: S<'a>,
1754 items: NonemptyMscVec<'a, T>,
1755 },
1756 Absent {
1757 spec: Option<Spec>,
1758 s: S<'a>,
1759 },
1760}
1761
1762impl<T: Unparse> SpecMscVec<'_, T> {
1763 fn new(spec: Option<Spec>, mut items: impl Iterator<Item = T>) -> Self {
1765 if let Some(first) = items.next() {
1766 SpecMscVec::Present {
1769 spec: spec.map(|spec| (spec, Default::default())),
1770 s: Default::default(),
1771 items: NonemptyMscVec::new(first, items),
1772 }
1773 } else {
1774 SpecMscVec::Absent {
1775 spec,
1776 s: Default::default(),
1777 }
1778 }
1779 }
1780
1781 fn len(&self) -> usize {
1782 match self {
1783 SpecMscVec::Present { items, .. } => items.len(),
1784 SpecMscVec::Absent { .. } => 0,
1785 }
1786 }
1787
1788 fn spec(&self) -> Option<Spec> {
1789 match self {
1790 SpecMscVec::Present {
1791 spec: Some((spec, _ms)),
1792 ..
1793 } => Some(*spec),
1794 SpecMscVec::Present { spec: None, .. } => None,
1795 SpecMscVec::Absent { spec, .. } => *spec,
1796 }
1797 }
1798
1799 fn iter(&self) -> impl Iterator<Item = &T> {
1800 let (first, tail) = match self {
1801 SpecMscVec::Absent { .. } => (None, None),
1802 SpecMscVec::Present {
1803 items: NonemptyMscVec { first, tail, .. },
1804 ..
1805 } => (Some(first.as_ref()), Some(tail)),
1806 };
1807 first
1808 .into_iter()
1809 .chain(tail.into_iter().flatten().map(|(_msc, i)| i))
1810 }
1811
1812 fn discard_own_encoding_indicator(&mut self) {
1818 match self {
1819 SpecMscVec::Absent { spec, .. } => *spec = None,
1820 SpecMscVec::Present { spec, s, .. } => {
1821 if let Some((_spec, ms)) = spec.take() {
1822 if ms != Default::default() {
1823 s.prefix(ms.0);
1826 }
1827 }
1828 }
1829 }
1830 }
1831}
1832
1833macro_rules! smv_concrete_impl {
1839 ($t:ident) => {
1840 impl<'a> SpecMscVec<'a, $t<'a>> {
1841 fn iter_mut(&mut self) -> impl Iterator<Item = &mut $t<'a>> {
1842 let (first, tail) = match self {
1843 SpecMscVec::Absent { .. } => (None, None),
1844 SpecMscVec::Present {
1845 items: NonemptyMscVec { first, tail, .. },
1846 ..
1847 } => (Some(first.as_mut()), Some(tail)),
1848 };
1849 first
1850 .into_iter()
1851 .chain(tail.into_iter().flatten().map(|(_msc, i)| i))
1852 }
1853
1854 fn cloned<'any>(&self) -> SpecMscVec<'any, $t<'any>> {
1857 match self {
1858 SpecMscVec::Present { spec, s, items } => SpecMscVec::Present {
1859 spec: spec.as_ref().map(|(spec, ms)| (*spec, ms.cloned())),
1860 s: s.cloned(),
1861 items: items.cloned(),
1862 },
1863 SpecMscVec::Absent { spec, s } => SpecMscVec::Absent {
1864 spec: spec.map(|s| s.clone()),
1865 s: s.cloned(),
1866 },
1867 }
1868 }
1869 }
1870 };
1871}
1872smv_concrete_impl!(Item);
1873smv_concrete_impl!(Kp);
1874
1875impl<'a> SpecMscVec<'a, Item<'a>> {
1876 fn visit(&mut self, visitor: &mut impl Visitor<'a>) {
1877 match self {
1878 SpecMscVec::Present { spec: _, s, items } => {
1879 items.visit(visitor).use_space_before(s).done();
1881 }
1882 SpecMscVec::Absent { spec: _, s: _ } => (),
1883 }
1884 }
1885}
1886impl<'a> SpecMscVec<'a, Kp<'a>> {
1888 fn visit(&mut self, visitor: &mut impl Visitor<'a>) {
1889 match self {
1890 SpecMscVec::Present { spec: _, s, items } => {
1891 items.visit(visitor).use_space_before(s).done();
1893 }
1894 SpecMscVec::Absent { spec: _, s: _ } => (),
1895 }
1896 }
1897}
1898
1899impl<T: Unparse> Unparse for SpecMscVec<'_, T> {
1900 fn serialize_write(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
1901 match self {
1902 SpecMscVec::Present { spec, s, items } => {
1903 if let Some((spec, msc)) = spec {
1904 spec.serialize_write(formatter)?;
1905 msc.serialize_write(formatter)?;
1906 }
1907 s.serialize_write(formatter)?;
1908 items.serialize_write(formatter)?;
1909 Ok(())
1910 }
1911 SpecMscVec::Absent { spec, s } => {
1912 if let Some(spec) = spec {
1913 spec.serialize_write(formatter)?;
1914 }
1915 s.serialize_write(formatter)?;
1916 Ok(())
1917 }
1918 }
1919 }
1920
1921 fn to_cbor(&self) -> Result<impl Iterator<Item = u8>, InconsistentEdn> {
1923 let collected: Result<Vec<_>, _> = self.iter().map(Unparse::to_cbor).collect();
1927 Ok(collected?.into_iter().flatten())
1928 }
1929}
1930
1931#[derive(Debug, Clone, PartialEq)]
1933struct Kp<'a> {
1934 key: Item<'a>,
1935 s0: S<'a>,
1936 s1: S<'a>,
1937 value: Item<'a>,
1938}
1939
1940impl<'a> Kp<'a> {
1941 fn new(key: Item<'a>, value: Item<'a>) -> Self {
1942 Self {
1943 key,
1944 s0: Default::default(),
1945 s1: Default::default(),
1946 value,
1947 }
1948 }
1949
1950 fn visit(&mut self, visitor: &mut impl Visitor<'a>) -> ProcessResult {
1951 let key_result = self.key.visit(visitor);
1952 let value_result = self.value.visit(visitor);
1953 key_result
1954 .use_space_after(&mut self.s0)
1955 .chain(value_result.use_space_before(&mut self.s1))
1956 }
1957
1958 fn cloned<'any>(&self) -> Kp<'any> {
1959 Kp {
1960 key: self.key.cloned(),
1961 s0: self.s0.cloned(),
1962 s1: self.s1.cloned(),
1963 value: self.value.cloned(),
1964 }
1965 }
1966}
1967
1968impl Unparse for Kp<'_> {
1969 fn serialize_write(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
1970 self.key.serialize_write(formatter)?;
1971 self.s0.serialize_write(formatter)?;
1972 formatter.write_str(":")?;
1973 self.s1.serialize_write(formatter)?;
1974 self.value.serialize_write(formatter)?;
1975 Ok(())
1976 }
1977
1978 fn to_cbor(&self) -> Result<impl Iterator<Item = u8>, InconsistentEdn> {
1979 Ok([self.key.to_cbor()?, self.value.to_cbor()?]
1980 .into_iter()
1981 .flatten())
1982 }
1983}
1984
1985#[derive(Debug, Clone, PartialEq)]
1986enum Simple<'a> {
1987 False,
1988 True,
1989 Null,
1990 Undefined,
1991 Numeric(Box<StandaloneItem<'a>>),
1993}
1994impl Simple<'_> {
1995 pub(crate) fn cloned<'any>(&self) -> Simple<'any> {
1996 match self {
1997 Simple::False => Simple::False,
1998 Simple::True => Simple::True,
1999 Simple::Null => Simple::Null,
2000 Simple::Undefined => Simple::Undefined,
2001 Simple::Numeric(standalone_item) => Simple::Numeric(Box::new(standalone_item.cloned())),
2002 }
2003 }
2004}
2005
2006impl Unparse for Simple<'_> {
2007 fn serialize_write(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
2008 match self {
2009 Simple::False => formatter.write_str("false")?,
2010 Simple::True => formatter.write_str("true")?,
2011 Simple::Null => formatter.write_str("null")?,
2012 Simple::Undefined => formatter.write_str("undefined")?,
2013 Simple::Numeric(i) => {
2014 formatter.write_str("simple(")?;
2015 i.serialize_write(formatter)?;
2016 formatter.write_str(")")?;
2017 }
2018 }
2019 Ok(())
2020 }
2021
2022 fn to_cbor(&self) -> Result<impl Iterator<Item = u8>, InconsistentEdn> {
2023 let mut result = Vec::new();
2024 match self {
2025 Simple::False => result.push(0xf4),
2026 Simple::True => result.push(0xf5),
2027 Simple::Null => result.push(0xf6),
2028 Simple::Undefined => result.push(0xf7),
2029 Simple::Numeric(i) => {
2030 let InnerItem::Number(ref number, spec) = i.inner() else {
2031 return Err(InconsistentEdn(
2032 "Items inside simple() need to be numbers for serialization.",
2033 ));
2034 };
2035 let NumberValue::Positive(number) = number.value() else {
2036 return Err(InconsistentEdn(
2037 "Non-positive numbers can not be in a Simple",
2038 ));
2039 };
2040 if number > 255 {
2041 return Err(InconsistentEdn("Spec exceeds valid range of 0..=255"));
2042 }
2043 let requested = Spec::encode_argument(spec.as_ref(), Major::FloatSimple, number)?;
2044 let permissible = Spec::encode_argument(None, Major::FloatSimple, number)?;
2045 if requested != permissible {
2046 return Err(InconsistentEdn(
2047 "Encoding indicators on simple value must use the preferred encoding",
2048 ));
2049 }
2050 result.extend(permissible);
2051 }
2052 };
2053 Ok(result.into_iter())
2054 }
2055}
2056
2057impl<'a> From<Simple<'a>> for Item<'a> {
2058 fn from(input: Simple<'a>) -> Self {
2059 InnerItem::Simple(input).into()
2060 }
2061}
2062
2063#[derive(Clone, Debug, PartialEq)]
2065enum InnerItem<'a> {
2066 Map(SpecMscVec<'a, Kp<'a>>),
2067 Array(SpecMscVec<'a, Item<'a>>),
2068 Tagged(u64, Option<Spec>, Box<StandaloneItem<'a>>),
2069 Number(Number<'a>, Option<Spec>),
2079 Simple(Simple<'a>),
2080 String(CborString<'a>),
2081 StreamString(MS<'a>, NonemptyMscVec<'a, CborString<'a>>),
2082}
2083
2084impl<'a> InnerItem<'a> {
2085 fn discard_encoding_indicators(&mut self) {
2087 match self {
2088 InnerItem::Map(items) => {
2089 for i in items.iter_mut() {
2090 i.key.discard_encoding_indicators();
2091 i.value.discard_encoding_indicators();
2092 }
2093 items.discard_own_encoding_indicator();
2094 }
2095 InnerItem::Array(items) => {
2096 for i in items.iter_mut() {
2097 i.discard_encoding_indicators();
2098 }
2099 items.discard_own_encoding_indicator();
2100 }
2101 InnerItem::Tagged(_n, spec, item) => {
2102 *spec = None;
2103 item.item_mut().discard_encoding_indicators();
2104 }
2105 InnerItem::Number(_n, spec) => {
2106 *spec = None;
2107 }
2108 InnerItem::Simple(Simple::Numeric(i)) => i.item_mut().discard_encoding_indicators(),
2109 InnerItem::Simple(_) => {}
2110 InnerItem::String(items) => {
2111 items.discard_encoding_indicators();
2112 }
2113 InnerItem::StreamString(_ms, items) => {
2114 for i in items.iter_mut() {
2117 i.discard_encoding_indicators();
2118 }
2119 }
2120 }
2121 }
2122
2123 fn set_delimiters(&mut self, policy: DelimiterPolicy) {
2124 use DelimiterPolicy::*;
2125
2126 let nested_policy = if let IndentedRegularSpacing {
2127 base_indent,
2128 indent_level,
2129 max_width,
2130 trailing_newline,
2131 } = policy
2132 {
2133 self.set_delimiters(SingleLineRegularSpacing);
2136 if self.serialize().len() + base_indent < max_width {
2137 return;
2138 }
2139
2140 IndentedRegularSpacing {
2141 base_indent: base_indent + indent_level,
2142 indent_level,
2143 max_width,
2144 trailing_newline,
2145 }
2146 } else {
2147 policy
2148 };
2149
2150 match self {
2151 InnerItem::Map(items) => match items {
2152 SpecMscVec::Absent { s, .. } => s.set_delimiters(nested_policy, false),
2153 SpecMscVec::Present { s, items, .. } => {
2154 s.set_delimiters(nested_policy, true);
2155 let set_on_item = |kp: &mut Kp| {
2156 kp.key.set_delimiters(nested_policy);
2157 kp.value.set_delimiters(nested_policy);
2158 kp.s0.set_delimiters(nested_policy, false);
2159 if matches!(policy, SingleLineRegularSpacing) {
2160 kp.s1.0 = " ".into();
2161 } else {
2162 kp.s1.set_delimiters(nested_policy, false);
2165 }
2166 };
2167 set_on_item(&mut items.first);
2168 for (msc, item) in items.tail.iter_mut() {
2169 set_on_item(item);
2170 msc.set_delimiters(nested_policy, true);
2171 }
2172 items.soc.set_delimiters(policy, true);
2173 }
2174 },
2175 InnerItem::Array(items) => match items {
2176 SpecMscVec::Absent { s, .. } => s.set_delimiters(nested_policy, false),
2177 SpecMscVec::Present { s, items, .. } => {
2178 s.set_delimiters(nested_policy, true);
2179 items.first.set_delimiters(nested_policy);
2180 for (msc, item) in items.tail.iter_mut() {
2181 item.set_delimiters(nested_policy);
2182 msc.set_delimiters(nested_policy, true);
2183 }
2184 items.soc.set_delimiters(policy, true);
2185 }
2186 },
2187 InnerItem::Tagged(_n, _spec, item) => {
2188 item.set_delimiters(nested_policy);
2189 }
2190 InnerItem::Number(_n, _spec) => {}
2191 InnerItem::Simple(Simple::Numeric(item)) => {
2192 item.0.set_delimiters(nested_policy, false);
2195 item.1.set_delimiters(nested_policy);
2196 item.2.set_delimiters(nested_policy, false);
2197 }
2198 InnerItem::Simple(_) => {}
2199 InnerItem::String(CborString { items, separators }) => {
2200 for i in items {
2201 i.set_delimiters(nested_policy);
2202 }
2203 for (sep_pre, sep_post) in separators {
2204 match nested_policy {
2205 SingleLineRegularSpacing => {
2206 sep_pre.set_delimiters(SingleSpace, true);
2207 sep_post.set_delimiters(SingleSpace, false);
2208 }
2209 _ => {
2210 sep_pre.set_delimiters(nested_policy, true);
2211 sep_post.set_delimiters(nested_policy, false);
2212 }
2213 }
2214 }
2215 }
2216 InnerItem::StreamString(ms, NonemptyMscVec { first, tail, soc }) => {
2217 ms.set_delimiters(nested_policy, true);
2218 first.set_delimiters(nested_policy);
2219 for (ms, item) in tail {
2220 ms.set_delimiters(nested_policy, true);
2221 item.set_delimiters(nested_policy);
2222 }
2223 soc.set_delimiters(policy, true);
2224 }
2225 }
2226 }
2227
2228 fn visit(&mut self, visitor: &mut impl Visitor<'a>) {
2229 match self {
2230 InnerItem::Map(spec_msc_vec) => {
2231 spec_msc_vec.visit(visitor);
2232 }
2233 InnerItem::Array(spec_msc_vec) => {
2234 spec_msc_vec.visit(visitor);
2235 }
2236 InnerItem::Tagged(_number, _spec, standalone_item) => {
2237 use transformable::sealed::Transformable;
2238 standalone_item.visit(visitor);
2242 }
2243 InnerItem::Number(_number, _spec) => (),
2244 InnerItem::Simple(_simple) => (),
2245 InnerItem::String(_cbor_string) => (),
2246 InnerItem::StreamString(_ms, _nonempty_msc_vec) => (),
2247 }
2248 }
2249
2250 fn cloned<'any>(&self) -> InnerItem<'any> {
2251 match self {
2252 InnerItem::Map(spec_msc_vec) => InnerItem::Map(spec_msc_vec.cloned()),
2253 InnerItem::Array(spec_msc_vec) => InnerItem::Array(spec_msc_vec.cloned()),
2254 InnerItem::Tagged(tag, spec, standalone_item) => {
2255 InnerItem::Tagged(*tag, *spec, Box::new(standalone_item.cloned()))
2256 }
2257 InnerItem::Number(number, spec) => InnerItem::Number(number.cloned(), *spec),
2258 InnerItem::Simple(simple) => InnerItem::Simple(simple.cloned()),
2259 InnerItem::String(cbor_string) => InnerItem::String(cbor_string.cloned()),
2260 InnerItem::StreamString(ms, nonempty_msc_vec) => {
2261 InnerItem::StreamString(ms.cloned(), nonempty_msc_vec.cloned())
2262 }
2263 }
2264 }
2265}
2266
2267impl Unparse for InnerItem<'_> {
2268 fn serialize_write(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
2269 match self {
2270 InnerItem::Map(items) => {
2271 write!(formatter, "{{")?;
2272 items.serialize_write(formatter)?;
2273 write!(formatter, "}}")?;
2274 Ok(())
2275 }
2276 InnerItem::Array(items) => {
2277 write!(formatter, "[")?;
2278 items.serialize_write(formatter)?;
2279 write!(formatter, "]")?;
2280 Ok(())
2281 }
2282 InnerItem::Tagged(n, spec, item) => {
2283 write!(formatter, "{}", n)?;
2284 if let Some(spec) = spec {
2285 spec.serialize_write(formatter)?;
2286 }
2287 formatter.write_str("(")?;
2288 item.serialize_write(formatter)?;
2289 formatter.write_str(")")?;
2290 Ok(())
2291 }
2292 InnerItem::Number(n, spec) => {
2293 formatter.write_str(&n.0)?;
2294 if let Some(spec) = spec {
2295 spec.serialize_write(formatter)?;
2296 }
2297 Ok(())
2298 }
2299 InnerItem::Simple(s) => s.serialize_write(formatter),
2300 InnerItem::String(s) => s.serialize_write(formatter),
2301 InnerItem::StreamString(ms, nmv) => {
2302 formatter.write_str("(_")?;
2303 ms.serialize_write(formatter)?;
2304 nmv.serialize_write(formatter)?;
2305 formatter.write_str(")")?;
2306 Ok(())
2307 }
2308 }
2309 }
2310
2311 fn to_cbor(&self) -> Result<impl Iterator<Item = u8>, InconsistentEdn> {
2312 let mut result = vec![];
2313 match self {
2314 InnerItem::Map(smv) => {
2315 let len = smv.len();
2316 let spec = smv.spec();
2317 let (head, tail) = Spec::encode_item_count(spec.as_ref(), Major::Map, len)?;
2318 result.extend(head);
2319 for i in smv.iter() {
2320 result.extend(i.to_cbor()?);
2321 }
2322 result.extend(tail);
2323 }
2324 InnerItem::Array(smv) => {
2325 let len = smv.len();
2326 let spec = smv.spec();
2327 let (head, tail) = Spec::encode_item_count(spec.as_ref(), Major::Array, len)?;
2328 result.extend(head);
2329 for i in smv.iter() {
2330 result.extend(i.to_cbor()?);
2331 }
2332 result.extend(tail);
2333 }
2334 InnerItem::Tagged(n, spec, item) => {
2335 result.extend(Spec::encode_argument(spec.as_ref(), Major::Tagged, *n)?);
2336 result.extend(item.to_cbor()?);
2337 }
2338 InnerItem::Number(n, spec) => match n.value() {
2339 NumberValue::Positive(n) => {
2340 result.extend(Spec::encode_argument(spec.as_ref(), Major::Unsigned, n)?)
2341 }
2342 NumberValue::Negative(n) => {
2343 result.extend(Spec::encode_argument(spec.as_ref(), Major::Negative, n)?)
2344 }
2345 NumberValue::Float(n) => result.extend(float::encode(n, *spec)?),
2346 NumberValue::Big(n) => match spec {
2347 None => {
2348 let (tag, positive) = if n >= num_bigint::BigInt::ZERO {
2349 (2, n)
2350 } else {
2351 (3, -n)
2352 };
2353 use num_traits::ops::bytes::ToBytes;
2354 result.extend(Spec::encode_argument(None, Major::Tagged, tag)?);
2355 let bytes = positive.to_be_bytes();
2356 result.extend(Spec::encode_argument(
2357 None,
2358 Major::ByteString,
2359 bytes
2360 .len()
2361 .try_into()
2362 .expect("Even on 128-bit systems, EDN does not exceed 64bit sizes"),
2363 )?);
2364 result.extend(bytes);
2365 }
2366 _ => {
2367 return Err(InconsistentEdn(
2368 "Encoding indicators not specified for bignums",
2369 ))
2370 }
2371 },
2372 },
2373 InnerItem::Simple(s) => result.extend(s.to_cbor()?),
2374 InnerItem::String(s) => result.extend(s.to_cbor()?),
2375 InnerItem::StreamString(_ms, NonemptyMscVec { first, tail, .. }) => {
2376 let major = first.encoded_major_type()?;
2377 if !matches!(major, Major::TextString | Major::ByteString) {
2378 return Err(InconsistentEdn(
2381 "Item in indefinite length string that is neither bytes nor string",
2382 ));
2383 }
2384 result.push(((major as u8) << 5) | 31);
2385 result.extend(first.to_cbor()?);
2386 for item in tail.iter() {
2387 if item.1.encoded_major_type()? != major {
2388 return Err(InconsistentEdn("Item in indefinite length string has different encoding than head element"));
2389 }
2390 result.extend(item.1.to_cbor()?);
2391 }
2392 result.push(0xff);
2393 }
2394 }
2395 Ok(result.into_iter())
2396 }
2397}
2398
2399#[derive(PartialEq, Debug, Copy, Clone)]
2400enum Major {
2401 Unsigned = 0,
2402 Negative = 1,
2403 ByteString = 2,
2404 TextString = 3,
2405 Array = 4,
2406 Map = 5,
2407 Tagged = 6,
2408 FloatSimple = 7,
2409}
2410
2411impl Major {
2412 fn from_byte(byte: u8) -> (Self, u8) {
2414 (
2415 match byte >> 5 {
2416 0 => Major::Unsigned,
2417 1 => Major::Negative,
2418 2 => Major::ByteString,
2419 3 => Major::TextString,
2420 4 => Major::Array,
2421 5 => Major::Map,
2422 6 => Major::Tagged,
2423 7 => Major::FloatSimple,
2424 _ => unreachable!(),
2425 },
2426 byte & 0x1f,
2427 )
2428 }
2429}
2430
2431#[derive(Copy, Clone, Debug, PartialEq)]
2441#[allow(non_camel_case_types)] enum Spec {
2443 S_,
2444 S_i,
2445 S_0,
2446 S_1,
2447 S_2,
2448 S_3,
2449}
2450
2451impl Spec {
2452 fn encode_item_count(
2456 self_: Option<&Self>,
2457 major: Major,
2458 count: usize,
2459 ) -> Result<(Vec<u8>, &[u8]), InconsistentEdn> {
2460 debug_assert!(matches!(major, Major::Map | Major::Array), "Encoding an item count only makes see for maps and arrays; strings work a bit different.");
2461 Ok((
2462 Spec::encode_argument(self_, major, count.try_into().expect("Even on 128bit architectures we can't have more than 64bit long counts of items"))?,
2463 if matches!(self_, Some(Spec::S_)) { [0xff].as_slice() } else { [].as_slice() },
2464 ))
2465 }
2466
2467 fn encode_argument(
2468 self_: Option<&Self>,
2469 major: Major,
2470 argument: u64,
2471 ) -> Result<Vec<u8>, InconsistentEdn> {
2472 let full_spec = match (self_, argument) {
2473 (None, 0..=23) => Self::S_i,
2474 (None, 0..=U8MAX) => Self::S_0,
2475 (None, 0..=U16MAX) => Self::S_1,
2476 (None, 0..=U32MAX) => Self::S_2,
2477 (None, _) => Self::S_3,
2478 (Some(s), _) => *s,
2479 };
2480
2481 let immediate_value = match full_spec {
2482 Self::S_ => 31,
2483 Self::S_i => {
2484 if argument < 24 {
2485 argument as u8
2486 } else {
2487 return Err(InconsistentEdn(
2488 "Immediate encoding demanded but value exceeds 23",
2489 ));
2490 }
2491 }
2492 Self::S_0 => 24,
2493 Self::S_1 => 25,
2494 Self::S_2 => 26,
2495 Self::S_3 => 27,
2496 };
2497 let first = core::iter::once(((major as u8) << 5) | immediate_value);
2498 Ok(match full_spec {
2499 Self::S_ | Self::S_i => first.collect(),
2500 Self::S_0 => first.chain(u8::try_from(argument)?.to_be_bytes()).collect(),
2501 Self::S_1 => first
2502 .chain(u16::try_from(argument)?.to_be_bytes())
2503 .collect(),
2504 Self::S_2 => first
2505 .chain(u32::try_from(argument)?.to_be_bytes())
2506 .collect(),
2507 Self::S_3 => first.chain(argument.to_be_bytes()).collect(),
2508 })
2509 }
2510
2511 fn serialize_write(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
2512 match self {
2513 Self::S_ => formatter.write_str("_"),
2514 Self::S_i => formatter.write_str("_i"),
2515 Self::S_0 => formatter.write_str("_0"),
2516 Self::S_1 => formatter.write_str("_1"),
2517 Self::S_2 => formatter.write_str("_2"),
2518 Self::S_3 => formatter.write_str("_3"),
2519 }
2520 }
2521
2522 fn or_none_if_default_for_arg(self, arg: u64) -> Option<Self> {
2528 const U8MAXPLUS: u64 = U8MAX + 1;
2529 const U16MAXPLUS: u64 = U16MAX + 1;
2530 const U32MAXPLUS: u64 = U32MAX + 1;
2531 match (self, arg) {
2532 (Spec::S_i, 0..=23) => None,
2533 (Spec::S_0, 24..=U8MAX) => None,
2534 (Spec::S_1, U8MAXPLUS..=U16MAX) => None,
2535 (Spec::S_2, U16MAXPLUS..=U32MAX) => None,
2536 (Spec::S_3, U32MAXPLUS..=u64::MAX) => None,
2537 (s, _) => Some(s),
2538 }
2539 }
2540}
2541
2542impl core::str::FromStr for Spec {
2543 type Err = &'static str;
2544
2545 fn from_str(s: &str) -> Result<Self, Self::Err> {
2546 match s {
2547 "" => Ok(Self::S_),
2548 "i" => Ok(Self::S_i),
2549 "0" => Ok(Self::S_0),
2550 "1" => Ok(Self::S_1),
2551 "2" => Ok(Self::S_2),
2552 "3" => Ok(Self::S_3),
2553 _ => Err("Unsupported encoding indicator"),
2554 }
2555 }
2556}
2557
2558#[allow(clippy::type_complexity)]
2563fn process_cbor_major_argument(
2566 cbor: &[u8],
2567) -> Result<(Major, Option<u64>, Spec, &[u8]), CborError> {
2568 let head = cbor
2572 .first()
2573 .ok_or(CborError::out_of_data("Expected item"))?;
2574
2575 let (major, additional) = Major::from_byte(*head);
2576 let tail = &cbor[1..];
2577
2578 let (argument, spec, skip): (Option<u64>, _, _) = match additional {
2579 0..=23 => (Some(additional.into()), Spec::S_i, 0),
2580 24 => (
2581 Some(
2582 tail.first()
2583 .copied()
2584 .ok_or(CborError::out_of_data("Missing 1 byte"))?
2585 .into(),
2586 ),
2587 Spec::S_0,
2588 1,
2589 ),
2590 25 => (
2591 Some(
2592 u16::from_be_bytes(
2593 tail.get(..2)
2594 .ok_or(CborError::out_of_data("Missing 2 bytes"))?
2595 .try_into()
2596 .unwrap(),
2597 )
2598 .into(),
2599 ),
2600 Spec::S_1,
2601 2,
2602 ),
2603 26 => (
2604 Some(
2605 u32::from_be_bytes(
2606 tail.get(..4)
2607 .ok_or(CborError::out_of_data("Missing 4 bytes"))?
2608 .try_into()
2609 .unwrap(),
2610 )
2611 .into(),
2612 ),
2613 Spec::S_2,
2614 4,
2615 ),
2616 27 => (
2617 Some(u64::from_be_bytes(
2618 tail.get(..8)
2619 .ok_or(CborError::out_of_data("Missing 8 bytes"))?
2620 .try_into()
2621 .unwrap(),
2622 )),
2623 Spec::S_3,
2624 8,
2625 ),
2626 31 => (None, Spec::S_, 0),
2627 _ => return Err(CborError::invalid("Reserved header byte")),
2628 };
2629
2630 Ok((major, argument, spec, &tail[skip..]))
2631}
2632
2633peg::parser! { grammar cbordiagnostic() for str {
2634
2635pub rule seq() -> Sequence<'input>
2637 = s0:S() items:(first:item() tail:(msc:MSC() inner:item() { (msc, inner) })* soc:SOC() { NonemptyMscVec::new_parsing(first, tail, soc) })? {
2638 Sequence { s0, items }
2639 }
2640
2641
2642pub rule one_item() -> StandaloneItem<'input>
2644 = s1:S() i:item() s2:S() { StandaloneItem(s1, i, s2) }
2645
2646rule item() -> Item<'input>
2650 = inner:(map() / array() / tagged() /
2651 number() / simple() /
2652 string:string() { InnerItem::String(string) } / streamstring()) { inner.into() }
2653
2654rule string1() -> String1e<'input>
2656 = value:$(tstr() / bstr()) spec:spec() {?
2657 Ok(if value.starts_with("<<") {
2658 String1e::EmbeddedChunk(cbordiagnostic::seq(&value[2..value.len() - 2]).map_err(|_| "Parse error in embedded CBOR")?, spec)
2661 } else {
2662 String1e::TextChunk(Cow::Borrowed(value), spec)
2663 })
2664 }
2665rule string1e() -> String1e<'input>
2667 = string1() / ellipsis()
2668rule ellipsis() -> String1e<'input>
2670 = dots:$("."*<3,>) { String1e::Ellipsis(dots.len()) }
2671rule string() -> CborString<'input>
2673 = head:string1e() tail:(separator:S() "+" s1:S() inner:string1e() { (separator, s1, inner) })* {
2674 CborString {
2675 items: core::iter::once(head).chain(tail.iter().map(|(_sep_pre, _sep_post, inner)| inner).cloned()).collect(),
2676 separators: tail.iter().map(|(sep_pre, sep_post, _inner)| (sep_pre.clone(), sep_post.clone())).collect()
2677 }
2678 }
2679
2680rule number() -> InnerItem<'input>
2683 = num:$((hexfloat() / hexint() / octint() / binint() / decnumber() / nonfin())) spec:spec() {InnerItem::Number(Number(Cow::Borrowed(num)), spec)}
2684
2685rule sign() -> Sign
2687 = "+" { Sign::Plus } / "-" { Sign::Minus }
2688
2689pub rule decnumber() -> NumberParts<'input>
2692 = sign:sign()? prepost:(predot:$(DIGIT()+) postdot:("." postdot:$(DIGIT()*) { postdot })? { (predot, postdot) } / "." postdot:$(DIGIT()+) { ("", Some(postdot)) })
2693 exponent:(['e'|'E'] sign:sign()? exponent:$(DIGIT()+) {(sign, exponent)})?
2694 {
2695 let (predot, postdot) = prepost;
2696 NumberParts {
2697 base: 10,
2698 sign,
2699 predot,
2700 postdot,
2701 exponent,
2702 }
2703 }
2704pub rule hexfloat() -> NumberParts<'input>
2707 = sign:sign()?
2708 "0" ['x'|'X']
2709 prepost:(
2710 predot:$(HEXDIG()+) postdot:("." postdot:$(HEXDIG()*) { postdot })?
2711 { (Some(predot), postdot) }
2712 / "." postdot:$(HEXDIG()+)
2713 { (None, Some(postdot)) }
2714 )
2715 ['p'|'P']
2716 expsign:sign()?
2717 exp:$(DIGIT()+)
2718 {
2719 NumberParts {
2720 base: 16,
2721 sign,
2722 predot: prepost.0.unwrap_or(""),
2723 postdot: prepost.1,
2724 exponent: Some((expsign, exp))
2725 }
2726 }
2727pub rule hexint() -> NumberParts<'input>
2729 = sign:sign()? "0" ['x'|'X'] predot:$(HEXDIG()+) { NumberParts {base: 16, sign, predot, postdot: None, exponent: None} }
2730pub rule octint() -> NumberParts<'input>
2732 = sign:sign()? "0" ['o'|'O'] predot:$(ODIGIT()+) { NumberParts {base: 8, sign, predot, postdot: None, exponent: None} }
2733pub rule binint() -> NumberParts<'input>
2735 = sign:sign()? "0" ['b'|'B'] predot:$(BDIGIT()+) { NumberParts {base: 2, sign, predot, postdot: None, exponent: None} }
2736rule nonfin()
2740 = "Infinity" / "-Infinity" / "NaN"
2741rule simple() -> InnerItem<'input>
2747 = "false" { InnerItem::Simple(Simple::False) }
2748 / "true" { InnerItem::Simple(Simple::True) }
2749 / "null" { InnerItem::Simple(Simple::Null) }
2750 / "undefined" { InnerItem::Simple(Simple::Undefined) }
2751 / "simple(" s1:S() i:item() s2:S() ")" {InnerItem::Simple(Simple::Numeric(Box::new(StandaloneItem(s1, i, s2))))}
2752rule uint() -> u64
2754 = n:$("0" / DIGIT1() DIGIT()*) {? n.parse().or(Err("Exceeding tag space")) }
2755rule tagged() -> InnerItem<'input>
2757 = tag:uint() tagspec:spec() "(" s0:S() value:item() s1:S() ")" { InnerItem::Tagged(tag, tagspec, Box::new(StandaloneItem(s0, value, s1))) }
2758
2759pub rule app_prefix() =
2762 quiet!{lcalpha() lcalnum()* / ucalpha() ucalnum()*} / expected!("application prefix")
2763pub rule app_string() -> (&'input str, String)
2765 = prefix:$(app_prefix()) data:sqstr() { (prefix, data) }
2766pub rule sqstr() -> String = SQUOTE() sqstr:single_quoted()* SQUOTE() { sqstr.iter().filter_map(|c| *c).collect() }
2770rule bstr()
2773 = app_string() / sqstr() / embedded()
2774pub rule tstr() -> String
2776 = DQUOTE() text:double_quoted()* DQUOTE() { text.iter().filter_map(|c| *c).collect() }
2777
2778rule embedded()
2780 = "<<" seq() ">>"
2781
2782rule array() -> InnerItem<'input>
2784 = "[" array:(
2785 spec:specms() s:S() first:item() tail:(msc:MSC() inner:item() { (msc, inner) })* soc:SOC()
2786 { SpecMscVec::Present { spec, s, items: NonemptyMscVec::new_parsing(first, tail, soc) } }
2787 / spec:spec() s:S()
2788 { SpecMscVec::Absent { spec, s } }
2789 ) "]"
2790 { InnerItem::Array(array) }
2791rule map() -> InnerItem<'input>
2793 = "{" map:(
2794 spec:specms() s:S() first:keyp() tail:(msc:MSC() inner:keyp() { (msc, inner) })* soc:SOC()
2795 { SpecMscVec::Present { spec, s, items: NonemptyMscVec::new_parsing(first, tail, soc) } }
2796 / spec:spec() s:S()
2797 { SpecMscVec::Absent { spec, s } }
2798 ) "}"
2799 { InnerItem::Map(map) }
2800rule keyp() -> Kp<'input>
2802 = key:item() s0:S() ":" s1:S() value:item() { Kp { key, s0, s1, value } }
2803
2804rule blank() -> ()
2807 = quiet!{"\x09" / "\x0A" / "\x0D" / "\x20"} / expected!("tabs, spaces or newlines")
2808
2809rule non_slash() -> ()
2811 = blank() / ['\x21'..='\x2e' | '\x30'..='\u{D7FF}' | '\u{E000}'..='\u{10FFFF}'] {}
2812rule non_lf() -> ()
2814 = ['\x09' | '\x0D' | '\x20'..='\u{D7FF}' | '\u{E000}'..='\u{10FFFF}'] {}
2815
2816rule comment() -> Comment
2819 = quiet!{"/" body:$(non_slash()*) "/" { Comment::Slashed } / "#" body:$(non_lf()*) "\x0A" { Comment::Hashed }} / expected!("comment")
2820
2821rule S() -> S<'input>
2826 = data:S_details() { S(Cow::Borrowed(data.data)) }
2827 pub(crate) rule S_details() -> SDetails<'input>
2828 = sliced:with_slice(<blank()* comments:(comment:comment() blank()* { comment })* { comments.last().cloned() }>) { SDetails { data: sliced.1, last_comment_style: sliced.0 } }
2829rule MS() -> MS<'input>
2832 = data:$( (blank() / comment() ) S()) { MS(Cow::Borrowed(data)) }
2833rule MSC() -> MSC<'input>
2836 = data:$( ("," S()) / (MS() ("," S())?) ) { MSC(Cow::Borrowed(data)) }
2837
2838rule SOC() -> SOC<'input>
2841 = data:$( SOC_details() ) { SOC(Cow::Borrowed(data)) }
2842 pub(crate) rule SOC_details() -> (SDetails<'input>, Option<SDetails<'input>>)
2843 = before:S_details() after:("," after:S_details() { after })? { (before, after) }
2844
2845rule streamstring() -> InnerItem<'input>
2849 = "(_" ms:MS() first:string() tail:(msc:MSC() inner:string() { (msc, inner) })* soc:SOC() ")" {
2850 InnerItem::StreamString(ms, NonemptyMscVec::new_parsing(first, tail, soc))
2851 }
2852
2853rule spec() -> Option<Spec>
2855 = quiet!{("_" spec:$(wordchar()*) {? spec.parse() })? } / expected!(r#"a valid encoding indicator ("_", "_i", "_0", "_1", "_2" or "_3")"#)
2856rule specms() -> Option<(Spec, MS<'input>)>
2858 = quiet!{("_" spec:$(wordchar()*) ms:MS() {? spec.parse().map(|spec| (spec, ms)) })? } / expected!(r#"a valid encoding indicator ("_", "_i", "_0", "_1", "_2" or "_3")"#)
2859
2860rule double_quoted() -> Option<char>
2865 = unescaped() /
2866 SQUOTE() { Some('\'') } /
2867 "\\" DQUOTE() { Some('"') } /
2868 "\\" e:escapable() { Some(e) }
2869
2870rule single_quoted() -> Option<char>
2875 = unescaped() / DQUOTE() { Some('"') } / "\\" SQUOTE() { Some('\'') } / "\\" e:escapable() { Some(e) }
2876
2877rule escapable() -> char
2886 = "b" { '\x08' }
2887 / "f" { '\x0c' }
2888 / "n" { '\n' }
2889 / "r" { '\r' }
2890 / "t" { '\t' }
2891 / "/" { '/' }
2892 / "\\" { '\\' }
2893 / h:("u" h:hexchar() { h }) { h }
2894
2895rule hexchar() -> char
2899 =
2900 "{" hex:$("0"+ hexscalar()? / hexscalar()) "}"
2901 {
2902 char::try_from(
2903 u32::from_str_radix(hex, 16)
2904 .expect("Syntax ensures this works")
2905 )
2906 .expect("Syntax rules out surrogate sequences and numbers beyond Unicode specification")
2907 }
2908 / hex:$(non_surrogate())
2909 {
2910 char::try_from(
2911 u32::from(
2912 u16::from_str_radix(hex, 16)
2913 .expect("Syntax ensures this works")
2914 )
2915 )
2916 .expect("Syntax rules out surrogate sequences and numbers beyond Unicode specification")
2917 }
2918 / hl:(h:$(high_surrogate()) "\\" "u" l:$(low_surrogate()) { format!("{h}{l}") } )
2919 {
2920 encoding_rs::UTF_16BE.decode(
2921 &u32::from_str_radix(&hl, 16)
2922 .expect("Syntax ensures this works")
2923 .to_be_bytes()
2924 )
2926 .0
2927 .chars()
2928 .next()
2929 .expect("Syntax ensures this produces exactly one valid character")
2930 }
2931rule non_surrogate()
2934 = ((DIGIT() / "A"/"B"/"C" / "E"/"F" / "a"/"b"/"c" / "e"/"f") HEXDIG()*<3,3>)
2935 / (("D" / "d") ODIGIT() HEXDIG()*<2,2> )
2936rule high_surrogate()
2938 = ("D" / "d") ("8"/"9"/"A"/"B"/"a"/"b") HEXDIG()*<2,2>
2939rule low_surrogate()
2941 = ("D" / "d") ("C"/"D"/"E"/"F" / "c"/"d"/"e"/"f") HEXDIG()*<2,2>
2942rule hexscalar()
2945 = "10" HEXDIG()*<4,4> / HEXDIG1() HEXDIG()*<4,4> / non_surrogate() / HEXDIG()*<1,3>
2946
2947rule unescaped() -> Option<char> = "\r" { None } / good:[ '\x0a' | '\x0D' | '\x20'..='\x21' | '\x23'..='\x26' | '\x28'..='\x5b' | '\x5d'..='\u{d7ff}' | '\u{e000}'..='\u{10ffff}' ] { Some(good) }
2960
2961rule DQUOTE() = "\""
2963rule SQUOTE() = "'"
2965
2966rule DIGIT() = quiet!{['0'..='9']} / expected!("digits")
2973 rule DIGIT1() = quiet!{['1'..='9']} / expected!("digits excluding 0")
2974 rule ODIGIT() = ['0'..='7']
2975 rule BDIGIT() = ['0'..='1']
2976 rule HEXDIG() -> u8 = n:$(DIGIT() / ['A'..='F' | 'a'..='f']) { u8::from_str_radix(n, 16).expect("Syntax ensures this is OK") }
2977 rule HEXDIG1() = DIGIT1() / ['A'..='F' | 'a'..='f']
2978
2979rule lcalpha() = ['a'..='z']
2986 rule lcalnum() = ['a'..='z'] / DIGIT()
2987 rule ucalpha() = ['A'..='Z']
2988 rule ucalnum() = ['A'..='Z'] / DIGIT()
2989 rule wordchar() = "_" / lcalnum() / ucalpha()
2990
2991pub rule app_string_h() -> Vec<u8> = S() byte:(high:HEXDIG() S() low:HEXDIG() S() { (high << 4) | low } / ellipsis() S() {? Err("Hex string was abbreviated") })*
2997 ("#" non_lf()*)?
2998 { byte }
2999
3000 rule with_slice<T>(r: rule<T>) -> (T, &'input str)
3005 = value:&r() input:$(r()) { (value, input) }
3006}}