1mod ion_eq;
2mod ion_ord;
3
4use std::cmp::Ordering;
5use std::fmt::{Display, Formatter};
6use std::ops::Deref;
7
8pub(crate) use ion_eq::{ion_eq_bool, ion_eq_f64, IonEq};
9pub(crate) use ion_ord::{ion_cmp_bool, ion_cmp_f64, IonOrd};
10
11#[derive(Debug, Clone)]
39pub struct IonData<T>(T);
40
41impl<T: IonEq> IonData<T> {
42 pub fn eq<R: Deref<Target = T>>(a: R, b: R) -> bool {
44 T::ion_eq(a.deref(), b.deref())
45 }
46
47 pub fn into_inner(self) -> T {
49 self.0
50 }
51}
52
53impl<T: IonEq> PartialEq for IonData<T> {
54 fn eq(&self, other: &Self) -> bool {
55 self.0.ion_eq(&other.0)
56 }
57}
58
59impl<T: IonEq> Eq for IonData<T> {}
60
61impl<T: IonEq> From<T> for IonData<T> {
62 fn from(value: T) -> Self {
63 IonData(value)
64 }
65}
66
67impl<T: IonEq> AsRef<T> for IonData<T> {
68 fn as_ref(&self) -> &T {
69 &self.0
70 }
71}
72
73impl<T: Display> Display for IonData<T> {
74 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
75 Display::fmt(&self.0, f)
76 }
77}
78
79impl<T: IonEq + IonOrd> PartialOrd for IonData<T> {
80 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
81 Some(IonOrd::ion_cmp(&self.0, &other.0))
82 }
83}
84
85impl<T: IonEq + IonOrd> Ord for IonData<T> {
86 fn cmp(&self, other: &Self) -> Ordering {
87 IonOrd::ion_cmp(&self.0, &other.0)
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use crate::ion_data::{IonEq, IonOrd};
94 use crate::{Element, IonData, Symbol};
95 use rstest::*;
96 use std::boxed::Box;
97 use std::fmt::Debug;
98 use std::pin::Pin;
99 use std::rc::Rc;
100 use std::sync::Arc;
101
102 #[rstest]
105 #[case::value(|s| Element::read_one(s).unwrap().value().clone().into())]
106 #[case::symbol(|s| Symbol::from(s).into())]
107 #[case::element(|s| Element::read_one(s).unwrap().into() )]
108 #[case::rc_element(|s| Rc::new(Element::read_one(s).unwrap()).into() )]
109 #[case::vec_element(|s| Element::read_all(s).unwrap().into() )]
110 #[case::rc_vec_element(|s| Rc::new(Element::read_all(s).unwrap()).into() )]
111 #[case::box_pin_rc_vec_box_arc_element(|s| Box::new(Pin::new(Rc::new(vec![Box::new(Arc::new(Element::read_one(s).unwrap()))]))).into() )]
112 fn can_wrap_data<T: IonEq + IonOrd + Debug>(
113 #[case] the_fn: impl Fn(&'static str) -> IonData<T>,
114 ) {
115 let id1: IonData<_> = the_fn("nan");
116 let id2: IonData<_> = the_fn("nan");
117 assert_eq!(id1, id2);
118
119 let id1: IonData<_> = the_fn("1.00");
120 let id2: IonData<_> = the_fn("1.0");
121 assert_ne!(id1, id2); assert!(id1 > id2); }
124}