Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mass renaming, container Display impls #486

Merged
merged 16 commits into from
Mar 16, 2023
105 changes: 86 additions & 19 deletions src/element/owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ impl List {
}
}

impl Display for List {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut ivf = IonValueFormatter { output: f };
ivf.format_list(self).map_err(|_| std::fmt::Error)?;
Ok(())
}
}

impl IonSequence for List {
fn iter(&self) -> ElementsIterator<'_> {
ElementsIterator::new(&self.children)
Expand Down Expand Up @@ -159,6 +167,14 @@ impl SExp {
}
}

impl Display for SExp {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut ivf = IonValueFormatter { output: f };
ivf.format_sexp(self).map_err(|_| std::fmt::Error)?;
Ok(())
}
}

impl IonSequence for SExp {
fn iter(&self) -> ElementsIterator<'_> {
ElementsIterator::new(&self.children)
Expand Down Expand Up @@ -250,6 +266,14 @@ pub struct Struct {
fields: Fields,
}

impl Display for Struct {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut ivf = IonValueFormatter { output: f };
ivf.format_struct(self).map_err(|_| std::fmt::Error)?;
Ok(())
}
}

impl Struct {
pub fn builder() -> StructBuilder {
StructBuilder::new()
Expand Down Expand Up @@ -417,6 +441,30 @@ pub enum Value {
Struct(Struct),
}

impl Display for Value {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut ivf = IonValueFormatter { output: f };
match &self {
Value::Null(ion_type) => ivf.format_null(*ion_type),
Value::Bool(bool) => ivf.format_bool(*bool),
Value::Integer(integer) => ivf.format_integer(integer),
Value::Float(float) => ivf.format_float(*float),
Value::Decimal(decimal) => ivf.format_decimal(decimal),
Value::Timestamp(timestamp) => ivf.format_timestamp(timestamp),
Value::Symbol(symbol) => ivf.format_symbol(symbol),
Value::String(string) => ivf.format_string(string),
Value::Clob(clob) => ivf.format_clob(clob),
Value::Blob(blob) => ivf.format_blob(blob),
Value::Struct(struct_) => ivf.format_struct(struct_),
Value::SExp(sexp) => ivf.format_sexp(sexp),
Value::List(list) => ivf.format_list(list),
}
.map_err(|_| std::fmt::Error)?;

Ok(())
}
}

/// An `(annotations, value)` pair representing an Ion value.
#[derive(Debug, Clone)]
pub struct Element {
Expand All @@ -434,28 +482,11 @@ impl Display for Element {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
let mut ivf = IonValueFormatter { output: f };

// display for annotations of this owned_element
// display for annotations of this element
ivf.format_annotations(&self.annotations)
.map_err(|_| std::fmt::Error)?;

match &self.value {
Value::Null(ion_type) => ivf.format_null(*ion_type),
Value::Bool(bool) => ivf.format_bool(*bool),
Value::Integer(integer) => ivf.format_integer(integer),
Value::Float(float) => ivf.format_float(*float),
Value::Decimal(decimal) => ivf.format_decimal(decimal),
Value::Timestamp(timestamp) => ivf.format_timestamp(timestamp),
Value::Symbol(symbol) => ivf.format_symbol(symbol),
Value::String(string) => ivf.format_string(string),
Value::Clob(clob) => ivf.format_clob(clob),
Value::Blob(blob) => ivf.format_blob(blob),
Value::Struct(struct_) => ivf.format_struct(struct_),
Value::SExp(sexp) => ivf.format_sexp(sexp),
Value::List(list) => ivf.format_list(list),
}
.map_err(|_| std::fmt::Error)?;

Ok(())
self.value.fmt(f)
}
}

Expand Down Expand Up @@ -867,4 +898,40 @@ mod value_tests {
}
}
}

#[test]
fn list_display_roundtrip() {
let list = ion_list![1, 2, 3, true, false];

// Use the Display impl to serialize the list to text
let text_list = format!("{list}");
// Parse the result and make sure it represents the same data
let expected_element: Element = list.into();
let actual_element = Element::read_one(text_list).unwrap();
assert!(expected_element.ion_eq(&actual_element));
}

#[test]
fn sexp_display_roundtrip() {
let sexp = ion_sexp! (1 2 3 true false);

// Use the Display impl to serialize the sexp to text
let text_sexp = format!("{sexp}");
// Parse the result and make sure it represents the same data
let expected_element: Element = sexp.into();
let actual_element = Element::read_one(text_sexp).unwrap();
assert!(expected_element.ion_eq(&actual_element));
}
Comment on lines +901 to +924
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just can't get over how neat these macros are. Great work, Zack and Matt!


#[test]
fn struct_display_roundtrip() {
let struct_ = ion_struct! {"foo": 1, "bar": 2, "baz": ion_list! [true, false]};

// Use the Display impl to serialize the struct to text
let text_struct = format!("{struct_}");
// Parse the result and make sure it represents the same data
let expected_element: Element = struct_.into();
let actual_element = Element::read_one(text_struct).unwrap();
assert!(expected_element.ion_eq(&actual_element));
}
}