1#![allow(clippy::result_large_err)]
10
11pub use annotations::{Annotations, IntoAnnotations};
24pub use sequence::Sequence;
25use std::cmp::Ordering;
26use std::fmt::{Display, Formatter};
27use std::hash::Hasher;
28use std::io;
29
30use crate::{ion_data, Decimal, Int, IonResult, IonType, Str, Symbol, SymbolRef, Timestamp};
31use crate::{Blob, Bytes, Clob, List, SExp, Struct};
32use crate::element::builders::{SequenceBuilder, StructBuilder};
34use crate::element::reader::ElementReader;
35use crate::ion_data::{IonDataHash, IonDataOrd, IonEq};
36use crate::lazy::any_encoding::AnyEncoding;
37use crate::lazy::encoding::Encoding;
38use crate::lazy::reader::Reader;
39use crate::lazy::streaming_raw_reader::{IonInput, IonSlice};
40use crate::location::SourceLocation;
41use crate::result::{
42 ConversionOperationError, ConversionOperationResult, IonTypeExpectation, TypeExpectation,
43};
44use crate::text::text_formatter::FmtValueFormatter;
45use crate::types::symbol::SymbolText;
46use crate::write_config::WriteConfig;
47
48mod annotations;
49pub(crate) mod iterators;
50
51pub mod builders;
52pub mod element_writer;
53pub mod reader;
54mod sequence;
55
56impl IonEq for Value {
57 fn ion_eq(&self, other: &Self) -> bool {
58 use Value::*;
59 match (self, other) {
60 (Null(this), Null(that)) => this == that,
61 (Bool(this), Bool(that)) => ion_data::ion_eq_bool(this, that),
62 (Int(this), Int(that)) => this.ion_eq(that),
63 (Float(this), Float(that)) => ion_data::ion_eq_f64(this, that),
64 (Decimal(this), Decimal(that)) => this.ion_eq(that),
65 (Timestamp(this), Timestamp(that)) => this.ion_eq(that),
66 (Symbol(this), Symbol(that)) => this.ion_eq(that),
67 (String(this), String(that)) => this.ion_eq(that),
68 (Clob(this), Clob(that)) => this.ion_eq(that),
69 (Blob(this), Blob(that)) => this.ion_eq(that),
70 (List(this), List(that)) => this.ion_eq(that),
71 (SExp(this), SExp(that)) => this.ion_eq(that),
72 (Struct(this), Struct(that)) => this.ion_eq(that),
73 _ => false,
74 }
75 }
76}
77
78impl IonDataOrd for Value {
79 fn ion_cmp(&self, other: &Self) -> Ordering {
80 use Value::*;
81
82 let ord = self.ion_type().ion_cmp(&other.ion_type());
84 if !ord.is_eq() {
85 return ord;
86 }
87
88 macro_rules! compare {
89 ($p:pat => $e:expr) => {
90 match other {
91 $p => $e,
92 Null(_) => Ordering::Greater,
93 _ => unreachable!("We already checked the Ion Type!"),
94 }
95 };
96 }
97
98 match self {
99 Null(_) => {
100 if let Null(_) = other {
101 Ordering::Equal
102 } else {
103 Ordering::Less
104 }
105 }
106 Bool(this) => compare!(Bool(that) => ion_data::ion_cmp_bool(this, that)),
107 Int(this) => compare!(Int(that) => this.ion_cmp(that)),
108 Float(this) => compare!(Float(that) => ion_data::ion_cmp_f64(this, that)),
109 Decimal(this) => compare!(Decimal(that) => this.ion_cmp(that)),
110 Timestamp(this) => compare!(Timestamp(that) => this.ion_cmp(that)),
111 Symbol(this) => compare!(Symbol(that) => this.ion_cmp(that)),
112 String(this) => compare!(String(that) => this.ion_cmp(that)),
113 Clob(this) => compare!(Clob(that) => this.ion_cmp(that)),
114 Blob(this) => compare!(Blob(that) => this.ion_cmp(that)),
115 List(this) => compare!(List(that) => this.ion_cmp(that)),
116 SExp(this) => compare!(SExp(that) => this.ion_cmp(that)),
117 Struct(this) => compare!(Struct(that) => this.ion_cmp(that)),
118 }
119 }
120}
121
122impl IonDataHash for Value {
123 fn ion_data_hash<H: Hasher>(&self, state: &mut H) {
124 use Value::*;
125 self.ion_type().ion_data_hash(state);
126 match self {
127 Null(_) => state.write_u8(0),
128 Bool(this) => ion_data::ion_data_hash_bool(*this, state),
129 Int(this) => this.ion_data_hash(state),
130 Float(this) => ion_data::ion_data_hash_f64(*this, state),
131 Decimal(this) => this.ion_data_hash(state),
132 Timestamp(this) => this.ion_data_hash(state),
133 Symbol(this) => this.ion_data_hash(state),
134 String(this) => this.ion_data_hash(state),
135 Clob(this) => this.ion_data_hash(state),
136 Blob(this) => this.ion_data_hash(state),
137 List(this) => this.ion_data_hash(state),
138 SExp(this) => this.ion_data_hash(state),
139 Struct(this) => this.ion_data_hash(state),
140 }
141 }
142}
143
144#[derive(Debug, Clone, PartialEq)]
146pub enum Value {
147 Null(IonType),
148 Bool(bool),
149 Int(Int),
150 Float(f64),
151 Decimal(Decimal),
152 Timestamp(Timestamp),
153 Symbol(Symbol),
154 String(Str),
155 Clob(Bytes),
156 Blob(Bytes),
157 List(Sequence),
158 SExp(Sequence),
159 Struct(Struct),
160}
161
162impl Value {
163 pub fn ion_type(&self) -> IonType {
164 use Value::*;
165
166 match self {
167 Null(t) => *t,
168 Bool(_) => IonType::Bool,
169 Int(_) => IonType::Int,
170 Float(_) => IonType::Float,
171 Decimal(_) => IonType::Decimal,
172 Timestamp(_) => IonType::Timestamp,
173 Symbol(_) => IonType::Symbol,
174 String(_) => IonType::String,
175 Clob(_) => IonType::Clob,
176 Blob(_) => IonType::Blob,
177 List(_) => IonType::List,
178 SExp(_) => IonType::SExp,
179 Struct(_) => IonType::Struct,
180 }
181 }
182}
183
184impl IonTypeExpectation for Value {
185 fn ion_type(&self) -> IonType {
186 self.ion_type()
187 }
188}
189
190impl Display for Value {
191 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
192 let mut ivf = FmtValueFormatter { output: f };
193 match &self {
194 Value::Null(ion_type) => ivf.format_null(*ion_type),
195 Value::Bool(bool) => ivf.format_bool(*bool),
196 Value::Int(integer) => ivf.format_integer(integer),
197 Value::Float(float) => ivf.format_float(*float),
198 Value::Decimal(decimal) => ivf.format_decimal(decimal),
199 Value::Timestamp(timestamp) => ivf.format_timestamp(timestamp),
200 Value::Symbol(symbol) => ivf.format_symbol(symbol),
201 Value::String(string) => ivf.format_string(string),
202 Value::Clob(clob) => ivf.format_clob(clob),
203 Value::Blob(blob) => ivf.format_blob(blob),
204 Value::List(sequence) => ivf.format_list(sequence),
205 Value::SExp(sequence) => ivf.format_sexp(sequence),
206 Value::Struct(struct_) => ivf.format_struct(struct_),
207 }
208 .map_err(|_| std::fmt::Error)?;
209
210 Ok(())
211 }
212}
213
214impl From<IonType> for Value {
215 fn from(ion_type: IonType) -> Self {
216 Value::Null(ion_type)
217 }
218}
219
220impl<I: Into<Int>> From<I> for Value {
223 fn from(value: I) -> Self {
224 let int: Int = value.into();
225 Value::Int(int)
226 }
227}
228
229impl From<f64> for Value {
230 fn from(f64_val: f64) -> Self {
231 Value::Float(f64_val)
232 }
233}
234
235impl From<Decimal> for Value {
236 fn from(decimal_val: Decimal) -> Self {
237 Value::Decimal(decimal_val)
238 }
239}
240
241impl From<Timestamp> for Value {
242 fn from(timestamp_val: Timestamp) -> Self {
243 Value::Timestamp(timestamp_val)
244 }
245}
246
247impl From<bool> for Value {
248 fn from(bool_val: bool) -> Self {
249 Value::Bool(bool_val)
250 }
251}
252
253impl From<&str> for Value {
254 fn from(string_val: &str) -> Self {
255 Value::String(string_val.into())
256 }
257}
258
259impl From<String> for Value {
260 fn from(value: String) -> Self {
261 let s: Str = value.into();
262 Value::String(s)
263 }
264}
265
266impl From<Str> for Value {
267 fn from(string_val: Str) -> Self {
268 Value::String(string_val)
269 }
270}
271
272impl From<Symbol> for Value {
273 fn from(sym_val: Symbol) -> Self {
274 Value::Symbol(sym_val)
275 }
276}
277
278impl From<SymbolRef<'_>> for Value {
279 fn from(sym_val: SymbolRef<'_>) -> Self {
280 Value::Symbol(sym_val.to_owned())
281 }
282}
283
284impl From<&[u8]> for Value {
285 fn from(value: &[u8]) -> Self {
286 Value::Blob(value.into())
287 }
288}
289
290impl From<Vec<u8>> for Value {
291 fn from(value: Vec<u8>) -> Self {
292 Value::Blob(value.into())
293 }
294}
295
296impl From<Blob> for Value {
297 fn from(blob: Blob) -> Self {
298 let bytes: Bytes = blob.into();
299 Value::Blob(bytes)
300 }
301}
302
303impl From<Clob> for Value {
304 fn from(clob: Clob) -> Self {
305 let bytes: Bytes = clob.into();
306 Value::Clob(bytes)
307 }
308}
309
310impl From<List> for Value {
311 fn from(list: List) -> Self {
312 Value::List(list.into())
313 }
314}
315
316impl From<SExp> for Value {
317 fn from(s_expr: SExp) -> Self {
318 Value::SExp(s_expr.into())
319 }
320}
321
322impl From<Struct> for Value {
323 fn from(struct_val: Struct) -> Self {
324 Value::Struct(struct_val)
325 }
326}
327
328pub trait IntoAnnotatedElement: Into<Value> {
345 fn with_annotations<I: IntoAnnotations>(self, annotations: I) -> Element {
347 Element::new(annotations.into_annotations(), self.into())
348 }
349}
350
351impl<V> IntoAnnotatedElement for V where V: Into<Value> {}
352
353impl IonEq for Element {
354 fn ion_eq(&self, other: &Self) -> bool {
355 self.annotations == other.annotations && self.value.ion_eq(&other.value)
356 }
357}
358
359impl IonDataOrd for Element {
364 fn ion_cmp(&self, other: &Self) -> Ordering {
365 let ord = self.ion_type().ion_cmp(&other.ion_type());
366 if !ord.is_eq() {
367 return ord;
368 }
369
370 let a1 = self.annotations();
371 let a2 = other.annotations();
372
373 let ord = a1.ion_cmp(a2);
374 if !ord.is_eq() {
375 return ord;
376 }
377
378 let v1 = self.value();
379 let v2 = other.value();
380 v1.ion_cmp(v2)
381 }
382}
383
384impl IonDataHash for Element {
385 fn ion_data_hash<H: Hasher>(&self, state: &mut H) {
386 self.annotations.ion_data_hash(state);
387 self.value.ion_data_hash(state);
388 }
389}
390
391#[derive(Clone)]
393pub struct Element {
394 annotations: Annotations,
395 value: Value,
396 location: SourceLocation,
398}
399
400impl std::fmt::Debug for Element {
401 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
402 <Element as Display>::fmt(self, f)
403 }
404}
405
406macro_rules! impl_try_from_element {
407 ($to_type:ident, $to_fn:ident) => {
408 impl TryFrom<Element> for $to_type {
409 type Error = ConversionOperationError<Element, $to_type>;
410
411 fn try_from(element: Element) -> ConversionOperationResult<Element, $to_type> {
412 element.$to_fn().into()
413 }
414 }
415 };
416}
417
418impl_try_from_element!(f64, try_into_float);
419impl_try_from_element!(Decimal, try_into_decimal);
420impl_try_from_element!(Timestamp, try_into_timestamp);
421impl_try_from_element!(String, try_into_text);
422impl_try_from_element!(Str, try_into_string);
423impl_try_from_element!(Symbol, try_into_symbol);
424impl_try_from_element!(bool, try_into_bool);
425impl_try_from_element!(Bytes, try_into_lob);
426impl_try_from_element!(Sequence, try_into_sequence);
427impl_try_from_element!(Struct, try_into_struct);
428
429impl Element {
430 pub(crate) fn new(annotations: Annotations, value: impl Into<Value>) -> Self {
431 Self {
432 annotations,
433 value: value.into(),
434 location: SourceLocation::empty(),
435 }
436 }
437
438 pub(crate) fn with_location(self, location: SourceLocation) -> Self {
439 Self {
440 annotations: self.annotations,
441 value: self.value,
442 location,
443 }
444 }
445
446 fn expected<ToType>(&self, maybe: Option<ToType>) -> IonResult<ToType>
447 where
448 ToType: TypeExpectation,
449 {
450 Ok(maybe.ok_or_else(|| ConversionOperationError::<&Element, ToType>::new(self))?)
451 }
452
453 pub fn value(&self) -> &Value {
465 &self.value
466 }
467
468 pub fn location(&self) -> &SourceLocation {
485 &self.location
486 }
487
488 pub fn into_value(self) -> Value {
490 self.value
491 }
492
493 pub fn into_annotations(self) -> Annotations {
495 self.annotations
496 }
497
498 pub fn into_parts(self) -> (Annotations, Value) {
500 (self.annotations, self.value)
501 }
502
503 pub fn null(null_type: IonType) -> Element {
504 null_type.into()
505 }
506
507 pub fn boolean(value: bool) -> Element {
508 value.into()
509 }
510
511 pub fn string<I: Into<Str>>(str: I) -> Element {
512 let text: Str = str.into();
513 text.into()
514 }
515
516 pub fn symbol<I: Into<Symbol>>(symbol: I) -> Element {
517 let symbol: Symbol = symbol.into();
518 symbol.into()
519 }
520
521 pub fn int<I: Into<Int>>(integer: I) -> Element {
522 let integer: Int = integer.into();
523 integer.into()
524 }
525
526 pub fn decimal(decimal: Decimal) -> Element {
527 decimal.into()
528 }
529
530 pub fn timestamp(timestamp: Timestamp) -> Element {
531 timestamp.into()
532 }
533
534 pub fn float(float: f64) -> Element {
535 float.into()
536 }
537
538 pub fn clob<A: AsRef<[u8]>>(bytes: A) -> Element {
539 let bytes: &[u8] = bytes.as_ref();
540 Value::Clob(bytes.into()).into()
541 }
542
543 pub fn blob<A: AsRef<[u8]>>(bytes: A) -> Element {
544 let bytes: &[u8] = bytes.as_ref();
545 Value::Blob(bytes.into()).into()
546 }
547
548 pub fn sequence_builder() -> SequenceBuilder {
549 Sequence::builder()
550 }
551
552 pub fn struct_builder() -> StructBuilder {
553 Struct::builder()
554 }
555
556 pub fn ion_type(&self) -> IonType {
557 self.value.ion_type()
558 }
559
560 pub fn annotations(&self) -> &Annotations {
561 &self.annotations
562 }
563
564 pub fn with_annotations<I: IntoAnnotations>(self, annotations: I) -> Self {
565 Element::new(annotations.into_annotations(), self.value)
566 }
567
568 pub fn is_null(&self) -> bool {
569 matches!(&self.value, Value::Null(_))
570 }
571
572 pub fn as_int(&self) -> Option<&Int> {
573 match &self.value {
574 Value::Int(i) => Some(i),
575 _ => None,
576 }
577 }
578
579 pub fn expect_int(&self) -> IonResult<&Int> {
580 self.expected(self.as_int())
581 }
582
583 pub fn try_into_int(self) -> ConversionOperationResult<Element, Int> {
584 match self.value {
585 Value::Int(i) => Ok(i),
586 _ => Err(self.into()),
587 }
588 }
589
590 pub fn as_i64(&self) -> Option<i64> {
591 match &self.value {
592 Value::Int(i) => i.as_i64(),
593 _ => None,
594 }
595 }
596
597 pub fn expect_i64(&self) -> IonResult<i64> {
598 self.expected(self.as_i64())
599 }
600
601 pub fn try_into_i64(self) -> ConversionOperationResult<Element, i64> {
602 match self.value {
603 Value::Int(i) if i.as_i64().is_some() => Ok(i.as_i64().unwrap()),
604 _ => Err(self.into()),
605 }
606 }
607
608 pub fn as_usize(&self) -> Option<usize> {
609 match &self.value {
610 Value::Int(i) => i.as_usize(),
611 _ => None,
612 }
613 }
614
615 pub fn expect_usize(&self) -> IonResult<usize> {
616 self.expected(self.as_usize())
617 }
618
619 pub fn try_into_usize(self) -> ConversionOperationResult<Element, usize> {
620 self.as_usize().ok_or_else(|| self.into())
621 }
622
623 pub fn as_float(&self) -> Option<f64> {
624 match &self.value {
625 Value::Float(f) => Some(*f),
626 _ => None,
627 }
628 }
629
630 pub fn expect_float(&self) -> IonResult<f64> {
631 self.expected(self.as_float())
632 }
633
634 pub fn try_into_float(self) -> ConversionOperationResult<Element, f64> {
635 match self.value {
636 Value::Float(f) => Ok(f),
637 _ => Err(self.into()),
638 }
639 }
640
641 pub fn as_decimal(&self) -> Option<Decimal> {
642 match &self.value {
643 Value::Decimal(d) => Some(d.clone()),
644 _ => None,
645 }
646 }
647
648 pub fn expect_decimal(&self) -> IonResult<Decimal> {
649 self.expected(self.as_decimal())
650 }
651
652 pub fn try_into_decimal(self) -> ConversionOperationResult<Element, Decimal> {
653 match self.value {
654 Value::Decimal(d) => Ok(d),
655 _ => Err(self.into()),
656 }
657 }
658
659 pub fn as_timestamp(&self) -> Option<Timestamp> {
660 match &self.value {
661 Value::Timestamp(t) => Some(t.clone()),
662 _ => None,
663 }
664 }
665
666 pub fn expect_timestamp(&self) -> IonResult<Timestamp> {
667 self.expected(self.as_timestamp())
668 }
669
670 pub fn try_into_timestamp(self) -> ConversionOperationResult<Element, Timestamp> {
671 match self.value {
672 Value::Timestamp(t) => Ok(t),
673 _ => Err(self.into()),
674 }
675 }
676
677 pub fn as_text(&self) -> Option<&str> {
678 match &self.value {
679 Value::String(text) => Some(text.as_ref()),
680 Value::Symbol(sym) => sym.text(),
681 _ => None,
682 }
683 }
684
685 pub fn expect_text(&self) -> IonResult<&str> {
686 self.expected(self.as_text())
687 }
688
689 pub fn try_into_text(self) -> ConversionOperationResult<Element, String> {
690 let Self {
691 value,
692 annotations,
693 location,
694 } = self;
695 match value {
696 Value::String(text) => Ok(text.to_string()),
697 Value::Symbol(sym) => match sym.text {
698 SymbolText::Shared(shared) => Ok((*shared).to_string()),
699 SymbolText::Owned(owned) => Ok(owned),
700 SymbolText::Unknown => {
701 let sym = Self {
702 value: Value::Symbol(Symbol::unknown_text()),
703 annotations,
704 location,
705 };
706 Err(ConversionOperationError::new(sym))
707 }
708 SymbolText::Static(static_str) => Ok((*static_str).to_string()),
709 },
710 _ => {
711 let sym = Self {
712 value,
713 annotations,
714 location,
715 };
716 Err(ConversionOperationError::new(sym))
717 }
718 }
719 }
720
721 pub fn as_string(&self) -> Option<&str> {
722 match &self.value {
723 Value::String(text) => Some(text.as_ref()),
724 _ => None,
725 }
726 }
727
728 pub fn expect_string(&self) -> IonResult<&str> {
729 self.expected(self.as_string())
730 }
731
732 pub fn try_into_string(self) -> ConversionOperationResult<Element, Str> {
733 match self.value {
734 Value::String(text) => Ok(text),
735 _ => Err(self.into()),
736 }
737 }
738
739 pub fn as_symbol(&self) -> Option<&Symbol> {
740 match &self.value {
741 Value::Symbol(sym) => Some(sym),
742 _ => None,
743 }
744 }
745
746 pub fn expect_symbol(&self) -> IonResult<&Symbol> {
747 self.expected(self.as_symbol())
748 }
749
750 pub fn try_into_symbol(self) -> ConversionOperationResult<Element, Symbol> {
751 match self.value {
752 Value::Symbol(sym) => Ok(sym),
753 _ => Err(self.into()),
754 }
755 }
756
757 pub fn as_bool(&self) -> Option<bool> {
758 match &self.value {
759 Value::Bool(b) => Some(*b),
760 _ => None,
761 }
762 }
763
764 pub fn expect_bool(&self) -> IonResult<bool> {
765 self.expected(self.as_bool())
766 }
767
768 pub fn try_into_bool(self) -> ConversionOperationResult<Element, bool> {
769 match self.value {
770 Value::Bool(b) => Ok(b),
771 _ => Err(self.into()),
772 }
773 }
774
775 pub fn as_lob(&self) -> Option<&[u8]> {
776 match &self.value {
777 Value::Blob(bytes) | Value::Clob(bytes) => Some(bytes.as_ref()),
778 _ => None,
779 }
780 }
781
782 pub fn expect_lob(&self) -> IonResult<&[u8]> {
783 self.expected(self.as_lob())
784 }
785
786 pub fn try_into_lob(self) -> ConversionOperationResult<Element, Bytes> {
787 match self.value {
788 Value::Blob(bytes) | Value::Clob(bytes) => Ok(bytes),
789 _ => Err(self.into()),
790 }
791 }
792
793 pub fn as_blob(&self) -> Option<&[u8]> {
794 match &self.value {
795 Value::Blob(bytes) => Some(bytes.as_ref()),
796 _ => None,
797 }
798 }
799
800 pub fn expect_blob(&self) -> IonResult<&[u8]> {
801 self.expected(self.as_blob())
802 }
803
804 pub fn try_into_blob(self) -> ConversionOperationResult<Element, Bytes> {
805 match self.value {
806 Value::Blob(bytes) => Ok(bytes),
807 _ => Err(self.into()),
808 }
809 }
810
811 pub fn as_clob(&self) -> Option<&[u8]> {
812 match &self.value {
813 Value::Clob(bytes) => Some(bytes.as_ref()),
814 _ => None,
815 }
816 }
817
818 pub fn expect_clob(&self) -> IonResult<&[u8]> {
819 self.expected(self.as_clob())
820 }
821
822 pub fn try_into_clob(self) -> ConversionOperationResult<Element, Bytes> {
823 match self.value {
824 Value::Clob(bytes) => Ok(bytes),
825 _ => Err(self.into()),
826 }
827 }
828
829 pub fn as_sequence(&self) -> Option<&Sequence> {
830 match &self.value {
831 Value::SExp(s) | Value::List(s) => Some(s),
832 _ => None,
833 }
834 }
835
836 pub fn expect_sequence(&self) -> IonResult<&Sequence> {
837 self.expected(self.as_sequence())
838 }
839
840 pub fn try_into_sequence(self) -> ConversionOperationResult<Element, Sequence> {
841 match self.value {
842 Value::SExp(s) | Value::List(s) => Ok(s),
843 _ => Err(self.into()),
844 }
845 }
846
847 pub fn as_list(&self) -> Option<&Sequence> {
848 match &self.value {
849 Value::List(s) => Some(s),
850 _ => None,
851 }
852 }
853
854 pub fn expect_list(&self) -> IonResult<&Sequence> {
855 self.expected(self.as_list())
856 }
857
858 pub fn try_into_list(self) -> ConversionOperationResult<Element, Sequence> {
859 match self.value {
860 Value::List(s) => Ok(s),
861 _ => Err(self.into()),
862 }
863 }
864
865 pub fn as_sexp(&self) -> Option<&Sequence> {
866 match &self.value {
867 Value::SExp(s) => Some(s),
868 _ => None,
869 }
870 }
871
872 pub fn expect_sexp(&self) -> IonResult<&Sequence> {
873 self.expected(self.as_sexp())
874 }
875
876 pub fn try_into_sexp(self) -> ConversionOperationResult<Element, Sequence> {
877 match self.value {
878 Value::SExp(s) => Ok(s),
879 _ => Err(self.into()),
880 }
881 }
882
883 pub fn as_struct(&self) -> Option<&Struct> {
884 match &self.value {
885 Value::Struct(structure) => Some(structure),
886 _ => None,
887 }
888 }
889
890 pub fn expect_struct(&self) -> IonResult<&Struct> {
891 self.expected(self.as_struct())
892 }
893
894 pub fn try_into_struct(self) -> ConversionOperationResult<Element, Struct> {
895 match self.value {
896 Value::Struct(structure) => Ok(structure),
897 _ => Err(self.into()),
898 }
899 }
900
901 pub fn read_first<A: AsRef<[u8]>>(data: A) -> IonResult<Option<Element>> {
907 let mut reader = Reader::new(AnyEncoding, IonSlice::new(data))?;
908 reader.read_next_element()
909 }
910
911 pub fn read_one<A: AsRef<[u8]>>(data: A) -> IonResult<Element> {
914 let mut reader = Reader::new(AnyEncoding, IonSlice::new(data))?;
915 reader.read_one_element()
916 }
917
918 pub fn read_all<A: AsRef<[u8]>>(data: A) -> IonResult<Sequence> {
923 Ok(Reader::new(AnyEncoding, IonSlice::new(data))?
924 .into_elements()
925 .collect::<IonResult<Vec<_>>>()?
926 .into())
927 }
928
929 pub fn iter<'a, I: IonInput + 'a>(
933 source: I,
934 ) -> IonResult<impl Iterator<Item = IonResult<Element>> + 'a> {
935 Ok(Reader::new(AnyEncoding, source)?.into_elements())
936 }
937
938 pub fn encode_as<E: Encoding, C: Into<WriteConfig<E>>>(
963 &self,
964 config: C,
965 ) -> IonResult<E::Output> {
966 config.into().encode(self)
967 }
968
969 pub fn encode_to<E: Encoding, C: Into<WriteConfig<E>>, W: io::Write>(
994 &self,
995 output: W,
996 config: C,
997 ) -> IonResult<W> {
998 config.into().encode_to(self, output)
999 }
1000}
1001
1002impl IonTypeExpectation for Element {
1003 fn ion_type(&self) -> IonType {
1004 Element::ion_type(self)
1005 }
1006}
1007
1008impl IonTypeExpectation for &Element {
1009 fn ion_type(&self) -> IonType {
1010 Element::ion_type(self)
1011 }
1012}
1013
1014impl Display for Element {
1015 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1016 let mut ivf = FmtValueFormatter { output: f };
1017
1018 ivf.format_annotations(&self.annotations)
1020 .map_err(|_| std::fmt::Error)?;
1021
1022 self.value.fmt(f)
1023 }
1024}
1025
1026impl PartialEq for Element {
1027 fn eq(&self, other: &Self) -> bool {
1028 self.value == other.value && self.annotations == other.annotations
1029 }
1030}
1031
1032impl<'a> From<&'a Element> for Element {
1035 fn from(element: &'a Element) -> Self {
1036 element.clone()
1037 }
1038}
1039
1040impl<T> From<T> for Element
1043where
1044 T: Into<Value>,
1045{
1046 fn from(value: T) -> Self {
1047 Element::new(Annotations::empty(), value.into())
1048 }
1049}
1050
1051impl AsRef<Element> for Element {
1052 fn as_ref(&self) -> &Element {
1053 self
1054 }
1055}
1056
1057#[cfg(test)]
1058mod tests {
1059 use chrono::*;
1060 use rstest::*;
1061 use std::collections::HashSet;
1062 use std::iter::{once, Once};
1063
1064 use ElemOp::*;
1065
1066 use crate::element::annotations::IntoAnnotations;
1067 use crate::{ion_list, ion_sexp, ion_struct, Decimal, Int, IonType, Symbol, Timestamp, Value};
1068 use crate::{Annotations, Element, IntoAnnotatedElement, Struct};
1069
1070 fn make_timestamp<T: AsRef<str>>(text: T) -> Timestamp {
1072 let dt = DateTime::parse_from_rfc3339(text.as_ref()).unwrap();
1073 Timestamp::from_fixed_offset_datetime(dt)
1074 }
1075
1076 struct CaseAnnotations {
1077 elem: Element,
1078 annotations: Annotations,
1079 }
1080
1081 fn annotations_text_case() -> CaseAnnotations {
1082 CaseAnnotations {
1083 elem: 10i64.with_annotations(["foo", "bar", "baz"]),
1084 annotations: ["foo", "bar", "baz"].into_annotations(),
1085 }
1086 }
1087
1088 fn no_annotations_case() -> CaseAnnotations {
1089 CaseAnnotations {
1090 elem: 10i64.into(),
1091 annotations: Annotations::empty(),
1092 }
1093 }
1094
1095 #[rstest]
1096 #[case::annotations_text(annotations_text_case())]
1097 #[case::no_annotations(no_annotations_case())]
1098 fn annotations_with_element(#[case] input: CaseAnnotations) {
1099 let actual: &Annotations = input.elem.annotations();
1100 let expected: &Annotations = &input.annotations;
1101 assert_eq!(actual, expected);
1102 }
1103
1104 struct CaseSym {
1105 eq_annotations: Vec<Symbol>,
1106 ne_annotations: Vec<Symbol>,
1107 }
1108
1109 fn sym_text_case() -> CaseSym {
1110 CaseSym {
1112 eq_annotations: vec![Symbol::owned("foo"), Symbol::owned("foo")],
1113 ne_annotations: vec![Symbol::owned("bar"), Symbol::owned("baz")],
1115 }
1116 }
1117
1118 #[rstest]
1121 #[case::owned_sym_text(sym_text_case())]
1122 fn symbol_token_eq(#[case] input: CaseSym) {
1123 for eq_this_token in &input.eq_annotations {
1125 for eq_other_token in &input.eq_annotations {
1126 assert_eq!(eq_this_token, eq_other_token);
1127 }
1128 }
1129
1130 for eq_token in &input.eq_annotations {
1133 for non_eq_token in &input.ne_annotations {
1134 assert_ne!(eq_token, non_eq_token);
1135 }
1136 }
1137 }
1138
1139 struct CaseStruct {
1141 eq_elements: Vec<Element>,
1143 ne_elements: Vec<Element>,
1145 }
1146
1147 fn ion_vec<E: Into<Element>, I: IntoIterator<Item = E>>(values: I) -> Vec<Element> {
1150 values.into_iter().map(|v| v.into()).collect()
1151 }
1152
1153 fn struct_with_multiple_fields_case() -> CaseStruct {
1154 CaseStruct {
1155 eq_elements: ion_vec([
1156 ion_struct! {
1158 "greetings": "hello",
1159 "name": "Ion"
1160 },
1161 ion_struct! {
1162 "name": "Ion",
1163 "greetings": "hello"
1164 },
1165 ]),
1166 ne_elements: ion_vec([
1167 ion_struct! {
1169 "greetings": "hello",
1170 "name": "Ion",
1171 "greetings": "hello"
1172 },
1173 ion_struct! {
1175 "greetings": "hello",
1176 "name": "Ion",
1177 "greetings": "bye"
1178 },
1179 ion_struct! {
1181 "greetings": "hello",
1182 "name": "Ion",
1183 "message": "bye"
1184 },
1185 ]),
1186 }
1187 }
1188
1189 fn struct_with_duplicates_in_multiple_fields_case() -> CaseStruct {
1190 CaseStruct {
1191 eq_elements: ion_vec([
1193 ion_struct! {
1194 "a" : 2i64,
1195 "a" : 2i64,
1196 "a" : 1i64
1197 },
1198 ion_struct! {
1199 "a" : 2i64,
1200 "a" : 1i64,
1201 "a" : 2i64
1202 },
1203 ion_struct! {
1204 "a" : 1i64,
1205 "a" : 2i64,
1206 "a" : 2i64
1207 },
1208 ]),
1209 ne_elements: ion_vec([
1210 ion_struct! {
1212 "a" : 1i64,
1213 "a" : 2i64
1214 },
1215 ion_struct! {
1217 "a" : 2i64,
1218 "a" : 1i64.with_annotations(["a"]),
1219 "a" : 2i64
1220 },
1221 ion_struct! {
1223 "a" : 2i64,
1224 "a" : 3i64,
1225 "a" : 2i64
1226 },
1227 ]),
1228 }
1229 }
1230
1231 fn struct_with_duplicate_fieldnames_case() -> CaseStruct {
1232 CaseStruct {
1233 eq_elements: ion_vec([
1234 ion_struct! {
1236 "greetings" : "world",
1237 "greetings" : "hello"
1238 },
1239 ion_struct! {
1240 "greetings" : "world",
1241 "greetings" : "hello"
1242 },
1243 ]),
1244 ne_elements: ion_vec([
1245 ion_struct! {
1247 "greetings" : "world",
1248 "greetings" : "hello",
1249 "greetings" : "hey"
1250 },
1251 ion_struct! {
1253 "greetings" : "world",
1254 "greetings" : "hello".with_annotations(["foo"])
1255 },
1256 ion_struct! {
1258 "greetings" : "world",
1259 "greetings" : "hello",
1260 "name" : "hello"
1261 },
1262 ]),
1263 }
1264 }
1265
1266 #[rstest]
1267 #[case::owned_struct_with_multiple_fields(struct_with_multiple_fields_case())]
1268 #[case::owned_struct_with_duplicates_in_multiple_fields(
1269 struct_with_duplicates_in_multiple_fields_case()
1270 )]
1271 #[case::owned_struct_with_duplicate_fieldnames(struct_with_duplicate_fieldnames_case())]
1272 fn struct_accessors(#[case] input: CaseStruct) {
1273 for eq_this_struct in &input.eq_elements {
1275 for eq_other_struct in &input.eq_elements {
1276 assert_eq!(eq_this_struct, eq_other_struct);
1277 }
1278 }
1279
1280 for eq_struct in &input.eq_elements {
1283 for non_eq_struct in &input.ne_elements {
1284 assert_ne!(eq_struct, non_eq_struct);
1285 }
1286 }
1287 }
1288
1289 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
1291 enum ElemOp {
1292 IsNull,
1293 AsBool,
1294 AsAnyInt,
1295 AsF64,
1296 AsDecimal,
1297 AsTimestamp,
1298 AsStr,
1299 AsSym,
1300 AsBytes,
1301 AsSequence,
1302 AsStruct,
1303 TryIntoInt,
1304 TryIntoI64,
1305 TryIntoF64,
1306 TryIntoDecimal,
1307 TryIntoTimestamp,
1308 TryIntoText,
1309 TryIntoString,
1310 TryIntoSymbol,
1311 TryIntoBool,
1312 TryIntoLob,
1313 TryIntoBlob,
1314 TryIntoClob,
1315 TryIntoSequence,
1316 TryIntoList,
1317 TryIntoSexp,
1318 TryIntoStruct,
1319 }
1320
1321 impl IntoIterator for ElemOp {
1322 type Item = ElemOp;
1323 type IntoIter = <Once<ElemOp> as IntoIterator>::IntoIter;
1324
1325 fn into_iter(self) -> Self::IntoIter {
1326 once(self)
1327 }
1328 }
1329
1330 type ElemAssertFn = Box<dyn FnOnce(&Element)>;
1331 type OwnedElemAssertFn = Box<dyn FnOnce(Element)>;
1332
1333 macro_rules! assert_pass_try_into {
1334 ($f:ident) => {
1335 Box::new(|e: Element| assert!(e.$f().is_ok()))
1336 };
1337 }
1338
1339 macro_rules! assert_fail_try_into {
1340 ($f:ident) => {
1341 Box::new(|e: Element| assert!(e.$f().is_err()))
1342 };
1343 }
1344
1345 struct Case {
1346 elem: Element,
1347 ion_type: IonType,
1348 ops: Vec<ElemOp>,
1349 op_assert: ElemAssertFn,
1350 owned_asserts: Vec<OwnedElemAssertFn>,
1351 }
1352
1353 fn null_case() -> Case {
1354 Case {
1355 elem: Element::from(IonType::Null), ion_type: IonType::Null,
1357 ops: vec![IsNull],
1358 op_assert: Box::new(|e: &Element| assert!(e.is_null())),
1359 owned_asserts: vec![],
1360 }
1361 }
1362
1363 fn bool_case() -> Case {
1364 Case {
1365 elem: true.into(),
1366 ion_type: IonType::Bool,
1367 ops: vec![AsBool, TryIntoBool],
1368 op_assert: Box::new(|e: &Element| {
1369 let _ = e.expect_bool().expect("expected bool");
1370 let expected = Element::from(true);
1371 assert_eq!(Some(true), e.as_bool());
1372 assert_eq!(&expected, e);
1373 }),
1374 owned_asserts: vec![Box::new(|e: Element| assert!(e.try_into_bool().is_ok()))],
1375 }
1376 }
1377
1378 fn i64_case() -> Case {
1379 Case {
1380 elem: 100.into(),
1381 ion_type: IonType::Int,
1382 ops: vec![AsAnyInt, TryIntoInt, TryIntoI64],
1383 op_assert: Box::new(|e: &Element| {
1384 let _ = e.expect_i64().expect("expected i64");
1385 let _ = e.expect_int().expect("expected int");
1386 let expected: Element = 100i64.into();
1387 assert_eq!(Some(&Int::from(100i64)), e.as_int());
1388 assert_eq!(Some(100), e.as_i64());
1389 assert_eq!(&expected, e);
1390 }),
1391 owned_asserts: vec![
1392 assert_pass_try_into!(try_into_i64),
1393 assert_pass_try_into!(try_into_int),
1394 ],
1395 }
1396 }
1397
1398 fn big_int_case() -> Case {
1399 Case {
1400 elem: ((i64::MAX as i128) + 1).into(),
1401 ion_type: IonType::Int,
1402 ops: vec![AsAnyInt, TryIntoInt],
1403 op_assert: Box::new(|e: &Element| {
1404 let _ = e.expect_int().expect("expected int");
1405 let expected: Element = 9223372036854775808i128.into();
1406 assert_eq!(Some(&Int::from(9223372036854775808i128)), e.as_int());
1407 assert_eq!(&expected, e);
1408 }),
1409 owned_asserts: vec![assert_pass_try_into!(try_into_int)],
1410 }
1411 }
1412
1413 fn f64_case() -> Case {
1414 Case {
1415 elem: 16.0.into(),
1416 ion_type: IonType::Float,
1417 ops: vec![AsF64, TryIntoF64],
1418 op_assert: Box::new(|e: &Element| {
1419 let _ = e.expect_float().expect("expected float");
1420 let expected = Element::from(16.0f64);
1421 assert_eq!(Some(16.0), e.as_float());
1422 assert_eq!(&expected, e);
1423 }),
1424 owned_asserts: vec![assert_pass_try_into!(try_into_float)],
1425 }
1426 }
1427
1428 fn timestamp_case() -> Case {
1429 Case {
1430 elem: make_timestamp("2014-10-16T12:01:00-00:00").into(),
1431 ion_type: IonType::Timestamp,
1432 ops: vec![AsTimestamp, TryIntoTimestamp],
1433 op_assert: Box::new(|e: &Element| {
1434 let _ = e.expect_timestamp().expect("expected timestamp");
1435 let expected: Element = make_timestamp("2014-10-16T12:01:00+00:00").into();
1436 assert_eq!(
1437 Some(make_timestamp("2014-10-16T12:01:00+00:00")),
1438 e.as_timestamp()
1439 );
1440 assert_eq!(&expected, e);
1441 }),
1442 owned_asserts: vec![assert_pass_try_into!(try_into_timestamp)],
1443 }
1444 }
1445
1446 fn decimal_case() -> Case {
1447 Case {
1448 elem: Decimal::new(8, 3).into(),
1449 ion_type: IonType::Decimal,
1450 ops: vec![AsDecimal, TryIntoDecimal],
1451 op_assert: Box::new(|e: &Element| {
1452 let _ = e.expect_decimal().expect("expected decimal");
1453 let expected: Element = Decimal::new(8, 3).into();
1454 assert_eq!(Some(Decimal::new(80, 2)), e.as_decimal());
1455 assert_eq!(&expected, e);
1456 }),
1457 owned_asserts: vec![assert_pass_try_into!(try_into_decimal)],
1458 }
1459 }
1460
1461 fn string_case() -> Case {
1462 Case {
1463 elem: "hello".into(),
1464 ion_type: IonType::String,
1465 ops: vec![AsStr, TryIntoText, TryIntoString],
1466 op_assert: Box::new(|e: &Element| {
1467 let _ = e.expect_text().expect("expected text");
1468 let _ = e.expect_string().expect("expected string");
1469 assert_eq!(Some("hello"), e.as_text())
1470 }),
1471 owned_asserts: vec![
1472 assert_pass_try_into!(try_into_text),
1473 assert_pass_try_into!(try_into_string),
1474 ],
1475 }
1476 }
1477
1478 fn symbol_case() -> Case {
1479 Case {
1480 elem: Symbol::owned("foo").into(),
1481 ion_type: IonType::Symbol,
1482 ops: vec![AsSym, AsStr, TryIntoText, TryIntoSymbol],
1483 op_assert: Box::new(|e: &Element| {
1484 let _ = e.expect_text().expect("expected text");
1485 let _ = e.expect_symbol().expect("expected symbol");
1486 assert_eq!(Some("foo"), e.as_symbol().unwrap().text());
1487 assert_eq!(Some("foo"), e.as_text());
1488 }),
1489 owned_asserts: vec![assert_pass_try_into!(try_into_symbol)],
1490 }
1491 }
1492
1493 fn blob_case() -> Case {
1494 Case {
1495 elem: Element::blob(b"hello"),
1496 ion_type: IonType::Blob,
1497 ops: vec![AsBytes, TryIntoLob, TryIntoBlob],
1498 op_assert: Box::new(|e: &Element| {
1499 let _ = e.expect_lob().expect("expected lob");
1500 let _ = e.expect_blob().expect("expected blob");
1501 assert_eq!(Some("hello".as_bytes()), e.as_lob())
1502 }),
1503 owned_asserts: vec![
1504 assert_pass_try_into!(try_into_lob),
1505 assert_pass_try_into!(try_into_blob),
1506 Box::new(|e: Element| {
1507 if let Value::Blob(bytes) = e.into_value() {
1508 let data: Vec<_> = bytes.into();
1509 assert_eq!(b"hello", data.as_slice());
1510 } else {
1511 panic!("expected blob");
1512 }
1513 }),
1514 ],
1515 }
1516 }
1517
1518 fn clob_case() -> Case {
1519 Case {
1520 elem: Element::clob(b"goodbye"),
1521 ion_type: IonType::Clob,
1522 ops: vec![AsBytes, TryIntoLob, TryIntoClob],
1523 op_assert: Box::new(|e: &Element| {
1524 let _ = e.expect_lob().expect("expected lob");
1525 let _ = e.expect_clob().expect("expected clob");
1526 assert_eq!(Some("goodbye".as_bytes()), e.as_lob())
1527 }),
1528 owned_asserts: vec![
1529 assert_pass_try_into!(try_into_lob),
1530 assert_pass_try_into!(try_into_clob),
1531 Box::new(|e: Element| {
1532 if let Value::Clob(bytes) = e.into_value() {
1533 let data: Vec<_> = bytes.into();
1534 assert_eq!(b"goodbye", data.as_slice());
1535 } else {
1536 panic!("expected clob");
1537 }
1538 }),
1539 ],
1540 }
1541 }
1542
1543 fn list_case() -> Case {
1544 Case {
1545 elem: ion_list![true, false].into(),
1546 ion_type: IonType::List,
1547 ops: vec![AsSequence, TryIntoList, TryIntoSequence],
1548 op_assert: Box::new(|e: &Element| {
1549 let _ = e.expect_list().expect("expected list");
1550 let _ = e.expect_sequence().expect("expected sequence");
1551 let actual = e.as_sequence().unwrap();
1552 let expected: Vec<Element> = ion_vec([true, false]);
1553 assert_eq!(2, actual.len());
1555 for (i, actual_item) in actual.elements().enumerate() {
1556 assert_eq!(&expected[i], actual_item);
1558 }
1559 assert!(!actual.is_empty());
1560 }),
1561 owned_asserts: vec![
1562 assert_pass_try_into!(try_into_list),
1563 assert_pass_try_into!(try_into_sequence),
1564 ],
1565 }
1566 }
1567
1568 fn sexp_case() -> Case {
1569 Case {
1570 elem: ion_sexp!(true false).into(),
1571 ion_type: IonType::SExp,
1572 ops: vec![AsSequence, TryIntoSexp, TryIntoSequence],
1573 op_assert: Box::new(|e: &Element| {
1574 let _ = e.expect_sexp().expect("expected sexp");
1575 let _ = e.expect_sequence().expect("expected sequence");
1576 let actual = e.as_sequence().unwrap();
1577 let expected: Vec<Element> = ion_vec([true, false]);
1578 assert_eq!(2, actual.len());
1580 for (i, actual_item) in actual.elements().enumerate() {
1581 assert_eq!(&expected[i], actual_item);
1583 }
1584 }),
1585 owned_asserts: vec![
1586 assert_pass_try_into!(try_into_sexp),
1587 assert_pass_try_into!(try_into_sequence),
1588 ],
1589 }
1590 }
1591
1592 fn struct_case() -> Case {
1593 Case {
1594 elem: ion_struct! {"greetings": "hello", "name": "ion"}.into(),
1595 ion_type: IonType::Struct,
1596 ops: vec![AsStruct, TryIntoStruct],
1597 op_assert: Box::new(|e: &Element| {
1598 let _ = e.expect_struct().expect("expected struct");
1599 let actual: &Struct = e.as_struct().unwrap();
1600
1601 assert_eq!(
1603 actual.iter().next(),
1604 Some((&"greetings".into(), &"hello".into()))
1605 );
1606
1607 assert_eq!(actual.get("greetings"), Some(&"hello".into()));
1608 }),
1609 owned_asserts: vec![assert_pass_try_into!(try_into_struct)],
1610 }
1611 }
1612 #[rstest]
1615 #[case::owned_null(null_case())]
1616 #[case::owned_bool(bool_case())]
1617 #[case::owned_i64(i64_case())]
1618 #[case::owned_big_int(big_int_case())]
1619 #[case::owned_f64(f64_case())]
1620 #[case::owned_decimal(decimal_case())]
1621 #[case::owned_timestamp(timestamp_case())]
1622 #[case::owned_string(string_case())]
1623 #[case::owned_blob(blob_case())]
1624 #[case::owned_clob(clob_case())]
1625 #[case::owned_list(list_case())]
1626 #[case::owned_sexp(sexp_case())]
1627 #[case::owned_struct(struct_case())]
1628 #[case::owned_symbol(symbol_case())]
1629 fn element_accessors(#[case] input_case: Case) {
1630 let neg_table: Vec<(ElemOp, ElemAssertFn)> = vec![
1632 (IsNull, Box::new(|e| assert!(!e.is_null()))),
1633 (AsBool, Box::new(|e| assert_eq!(None, e.as_bool()))),
1634 (
1635 AsAnyInt,
1636 Box::new(|e| {
1637 assert_eq!(None, e.as_int());
1638 assert_eq!(None, e.as_i64());
1639 }),
1640 ),
1641 (AsF64, Box::new(|e| assert_eq!(None, e.as_float()))),
1642 (AsDecimal, Box::new(|e| assert_eq!(None, e.as_decimal()))),
1643 (
1644 AsTimestamp,
1645 Box::new(|e| assert_eq!(None, e.as_timestamp())),
1646 ),
1647 (AsStr, Box::new(|e| assert_eq!(None, e.as_text()))),
1648 (AsSym, Box::new(|e| assert_eq!(None, e.as_symbol()))),
1649 (AsBytes, Box::new(|e| assert_eq!(None, e.as_lob()))),
1650 (AsSequence, Box::new(|e| assert!(e.as_sequence().is_none()))),
1651 (AsStruct, Box::new(|e| assert_eq!(None, e.as_struct()))),
1652 ];
1653
1654 let owned_neg_table: Vec<(ElemOp, OwnedElemAssertFn)> = vec![
1655 (TryIntoInt, assert_fail_try_into!(try_into_int)),
1656 (TryIntoI64, assert_fail_try_into!(try_into_i64)),
1657 (TryIntoF64, assert_fail_try_into!(try_into_float)),
1658 (TryIntoDecimal, assert_fail_try_into!(try_into_decimal)),
1659 (TryIntoTimestamp, assert_fail_try_into!(try_into_timestamp)),
1660 (TryIntoText, assert_fail_try_into!(try_into_text)),
1661 (TryIntoString, assert_fail_try_into!(try_into_string)),
1662 (TryIntoSymbol, assert_fail_try_into!(try_into_symbol)),
1663 (TryIntoBool, assert_fail_try_into!(try_into_bool)),
1664 (TryIntoLob, assert_fail_try_into!(try_into_lob)),
1665 (TryIntoBlob, assert_fail_try_into!(try_into_blob)),
1666 (TryIntoClob, assert_fail_try_into!(try_into_clob)),
1667 (TryIntoSequence, assert_fail_try_into!(try_into_sequence)),
1668 (TryIntoList, assert_fail_try_into!(try_into_list)),
1669 (TryIntoSexp, assert_fail_try_into!(try_into_sexp)),
1670 (TryIntoStruct, assert_fail_try_into!(try_into_struct)),
1671 ];
1672
1673 let valid_ops: HashSet<ElemOp> = input_case.ops.into_iter().collect();
1676 let borrowed_pos = once(input_case.op_assert);
1677 let owned_pos = input_case.owned_asserts.into_iter();
1678 let borrowed_neg = neg_table
1679 .into_iter()
1680 .filter_map(|(op, f)| (!valid_ops.contains(&op)).then_some(f));
1681 let owned_neg = owned_neg_table
1682 .into_iter()
1683 .filter_map(|(op, f)| (!valid_ops.contains(&op)).then_some(f));
1684 let borrowed = borrowed_pos.chain(borrowed_neg);
1685 let owned = owned_pos
1686 .chain(owned_neg)
1687 .map(|owned_fn| Box::new(|e: &Element| owned_fn(e.clone())) as ElemAssertFn);
1688 let op_assertions: Vec<ElemAssertFn> = borrowed.chain(owned).collect();
1689
1690 assert_eq!(input_case.ion_type, input_case.elem.ion_type());
1692
1693 let val_ref = input_case.elem.value();
1695 let ann_ref = input_case.elem.annotations();
1696 let val_owned = input_case.elem.clone().into_value();
1697 let ann_owned = input_case.elem.clone().into_annotations();
1698 let (ann_owned2, val_owned2) = input_case.elem.clone().into_parts();
1699 assert_eq!(val_ref, &val_owned);
1700 assert_eq!(val_owned, val_owned2);
1701 assert_eq!(ann_ref, &ann_owned);
1702 assert_eq!(ann_owned, ann_owned2);
1703
1704 for assert in op_assertions {
1706 assert(&input_case.elem);
1707 }
1708
1709 let itself = &input_case.elem;
1712 assert_eq!(&input_case.elem, itself);
1713 }
1714}
1715
1716#[cfg(test)]
1717mod value_tests {
1718 use std::fmt::Debug;
1719
1720 use rstest::*;
1721
1722 use crate::element::*;
1723 use crate::ion_data::IonEq;
1724 use crate::types::UInt;
1725 use crate::{ion_list, ion_sexp, ion_struct, IonType};
1726
1727 #[test]
1728 fn demonstrate_element_implements_send() {
1729 use std::thread;
1730 let list: Element = ion_list![1, 2, 3].into();
1736 thread::scope(|_| {
1737 let elements = [list];
1739 assert_eq!(elements.len(), 1);
1741 });
1742 }
1743
1744 #[rstest]
1745 #[case::strings(
1746 Element::from("hello"), "hello" )]
1749 #[case::symbols(
1750 Element::from(Symbol::owned("hello")), Symbol::owned("hello") )]
1753 #[case::struct_(
1754 ion_struct!{"greetings": "hello"},
1755 Element::read_one(r#"{greetings: "hello"}"#).unwrap()
1756 )]
1757 #[case::strings(
1758 Element::from("hello"), "hello" )]
1761 #[case::symbols(
1762 Element::from(Symbol::owned("hello")), Symbol::owned("hello") )]
1765 #[case::struct_(
1766 ion_struct!{"greetings": "hello"},
1767 Element::read_one(r#"{greetings: "hello"}"#).unwrap()
1768 )]
1769 fn owned_element_accessors<E1, E2>(#[case] e1: E1, #[case] e2: E2)
1770 where
1771 E1: Into<Element>,
1772 E2: Into<Element>,
1773 {
1774 assert_eq!(e1.into(), e2.into());
1776 }
1777
1778 #[rstest]
1779 #[case::struct_(ion_struct!{"greetings": "hello", "name": "Ion"}, 2)]
1780 #[case::list(ion_list!["greetings", 5, true], 3)]
1781 #[case::sexp(ion_sexp!(5 true), 2)]
1782 fn owned_container_len_test<I: Into<Element>>(#[case] container: I, #[case] length: usize) {
1783 let container = container.into();
1784 match container.ion_type() {
1785 IonType::List | IonType::SExp => {
1786 assert_eq!(container.as_sequence().unwrap().len(), length);
1788 }
1789 IonType::Struct => {
1790 assert_eq!(container.as_struct().unwrap().len(), length);
1792 }
1793 _ => {
1794 unreachable!("This test is only for container type elements")
1795 }
1796 }
1797 }
1798
1799 #[rstest]
1800 #[case::struct_(ion_struct!{"greetings": "hello", "name": "Ion"}, false)]
1801 #[case::list(ion_list!["greetings", 5, true], false)]
1802 #[case::list_empty(ion_list![], true)]
1803 #[case::sexp(ion_sexp!(5 true), false)]
1804 #[case::sexp_empty(ion_sexp!(), true)]
1805 fn owned_container_is_empty_test<I: Into<Element>>(
1806 #[case] container: I,
1807 #[case] is_empty: bool,
1808 ) {
1809 let container = container.into();
1810 match container.ion_type() {
1811 IonType::List | IonType::SExp => {
1812 assert_eq!(container.as_sequence().unwrap().is_empty(), is_empty);
1814 }
1815 IonType::Struct => {
1816 assert_eq!(container.as_struct().unwrap().is_empty(), is_empty);
1818 }
1819 _ => {
1820 unreachable!("This test is only for container type elements")
1821 }
1822 }
1823 }
1824
1825 #[test]
1826 fn list_display_roundtrip() {
1827 let list = ion_list![1, 2, 3, true, false];
1828
1829 let text_list = format!("{list}");
1831 let expected_element: Element = list.into();
1833 let actual_element = Element::read_one(text_list).unwrap();
1834 assert!(expected_element.ion_eq(&actual_element));
1835 }
1836
1837 #[test]
1838 fn sexp_display_roundtrip() {
1839 let sexp = ion_sexp! (1 2 3 true false);
1840
1841 let text_sexp = format!("{sexp}");
1843 let expected_element: Element = sexp.into();
1845 let actual_element = Element::read_one(text_sexp).unwrap();
1846 assert!(expected_element.ion_eq(&actual_element));
1847 }
1848
1849 #[test]
1850 fn struct_display_roundtrip() {
1851 let struct_ = ion_struct! {"foo": 1, "bar": 2, "baz": ion_list! [true, false]};
1852
1853 let text_struct = format!("{struct_}");
1855 let expected_element: Element = struct_.into();
1857 let actual_element = Element::read_one(text_struct).unwrap();
1858 assert!(expected_element.ion_eq(&actual_element));
1859 }
1860
1861 #[rstest]
1862 #[case::i8(42i8)]
1863 #[case::i8_neg(-42i8)]
1864 #[case::i16(42i16)]
1865 #[case::i16_neg(-42i16)]
1866 #[case::i32(42i32)]
1867 #[case::i32_neg(-42i32)]
1868 #[case::i64(42i64)]
1869 #[case::i64_neg(-42i64)]
1870 #[case::i128(42i128)]
1871 #[case::i128_neg(-42i128)]
1872 #[case::isize(42isize)]
1873 #[case::isize_neg(-42isize)]
1874 #[case::int(Int::from(42i64))]
1875 #[case::int_neg(Int::from(-42i64))]
1876 #[case::u8(42u8)]
1877 #[case::u16(42u16)]
1878 #[case::u32(42u32)]
1879 #[case::u64(42u64)]
1880 #[case::u128(42u128)]
1881 #[case::usize(42usize)]
1882 #[case::uint(UInt::from(42u64))]
1883 fn element_from_int<I, E>(#[case] source_int: I)
1884 where
1885 E: Debug,
1886 I: TryInto<Int, Error = E>,
1887 {
1888 let int: Int = source_int.try_into().unwrap();
1889 let element: Element = int.clone().into();
1890 assert_eq!(element.expect_i64(), int.expect_i64())
1891 }
1892
1893 #[rstest]
1894 fn read_a_symbol_terminated_by_end_of_input(
1895 #[values(
1896 "a","b","c","d","e","f","g","h","i","j",
1897 "k","l","m","n","o","p","q","r","s","t",
1898 "fa", "fal", "fals",
1901 "na", "nu", "nul",
1902 "tr", "tru",
1903 "$ion_",
1904 "$ion_1",
1905 "$ion_1_",
1906 )]
1907 input: &str,
1908 ) -> IonResult<()> {
1909 let value = Element::read_one(input)?;
1910 let actual_text = value.as_symbol().unwrap().text().unwrap();
1911 assert_eq!(actual_text, input);
1912 Ok(())
1913 }
1914}