Skip to content

Commit

Permalink
Stop impl Display for Element from panicking on typed nulls (#451)
Browse files Browse the repository at this point in the history
  • Loading branch information
popematt authored Dec 7, 2022
1 parent aa33f0f commit acac4ae
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 24 deletions.
18 changes: 9 additions & 9 deletions src/text/text_formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ impl<'a, W: std::fmt::Write> IonValueFormatter<'a, W> {
}

pub(crate) fn format_struct(&mut self, value: &Struct) -> IonResult<()> {
write!(self.output, "{{ ")?;
write!(self.output, "{{")?;
let mut peekable_itr = value.iter().peekable();
while let Some((field_name, field_value)) = peekable_itr.next() {
self.format_symbol(field_name.text().unwrap())?;
Expand All @@ -414,12 +414,12 @@ impl<'a, W: std::fmt::Write> IonValueFormatter<'a, W> {
write!(self.output, ", ")?;
}
}
write!(self.output, " }}")?;
write!(self.output, "}}")?;
Ok(())
}

pub(crate) fn format_sexp(&mut self, value: &Sequence) -> IonResult<()> {
write!(self.output, "( ")?;
write!(self.output, "(")?;
let mut peekable_itr = value.iter().peekable();
while peekable_itr.peek().is_some() {
let sexp_value = peekable_itr.next().unwrap();
Expand All @@ -428,12 +428,12 @@ impl<'a, W: std::fmt::Write> IonValueFormatter<'a, W> {
write!(self.output, " ")?;
}
}
write!(self.output, " )")?;
write!(self.output, ")")?;
Ok(())
}

pub(crate) fn format_list(&mut self, value: &Sequence) -> IonResult<()> {
write!(self.output, "[ ")?;
write!(self.output, "[")?;
let mut peekable_itr = value.iter().peekable();
while peekable_itr.peek().is_some() {
let list_value = peekable_itr.next().unwrap();
Expand All @@ -442,7 +442,7 @@ impl<'a, W: std::fmt::Write> IonValueFormatter<'a, W> {
write!(self.output, ", ")?;
}
}
write!(self.output, " ]")?;
write!(self.output, "]")?;
Ok(())
}
}
Expand Down Expand Up @@ -555,7 +555,7 @@ mod formatter_test {
vec![("greetings", Element::from(Value::String("hello".into())))].into_iter(),
))
},
"{ greetings: \"hello\" }",
"{greetings: \"hello\"}",
);
Ok(())
}
Expand All @@ -568,7 +568,7 @@ mod formatter_test {
vec!["hello".to_owned().into(), 5.into(), true.into()].into_iter(),
))
},
"( \"hello\" 5 true )",
"(\"hello\" 5 true)",
);
Ok(())
}
Expand All @@ -581,7 +581,7 @@ mod formatter_test {
vec!["hello".to_owned().into(), 5.into(), true.into()].into_iter(),
))
},
"[ \"hello\", 5, true ]",
"[\"hello\", 5, true]",
);
Ok(())
}
Expand Down
30 changes: 15 additions & 15 deletions src/value/owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ pub enum Value {
Struct(Struct),
}

/// An owned implementation of [`Element`]
/// An owned implementation of [`IonElement`]
#[derive(Debug, Clone)]
pub struct Element {
annotations: Vec<Symbol>,
Expand All @@ -461,20 +461,20 @@ impl Display for Element {
ivf.format_annotations(&self.annotations)
.map_err(|_| std::fmt::Error)?;

match self.ion_type() {
IonType::Null => ivf.format_null(IonType::Null),
IonType::Boolean => ivf.format_bool(self.as_bool().unwrap()),
IonType::Integer => ivf.format_integer(self.as_integer().unwrap()),
IonType::Float => ivf.format_float(self.as_f64().unwrap()),
IonType::Decimal => ivf.format_decimal(self.as_decimal().unwrap()),
IonType::Timestamp => ivf.format_timestamp(self.as_timestamp().unwrap()),
IonType::Symbol => ivf.format_symbol(self.as_str().unwrap()),
IonType::String => ivf.format_string(self.as_str().unwrap()),
IonType::Clob => ivf.format_clob(self.as_bytes().unwrap()),
IonType::Blob => ivf.format_blob(self.as_bytes().unwrap()),
IonType::Struct => ivf.format_struct(self.as_struct().unwrap()),
IonType::SExpression => ivf.format_sexp(self.as_sequence().unwrap()),
IonType::List => ivf.format_list(self.as_sequence().unwrap()),
match &self.value {
Value::Null(ion_type) => ivf.format_null(*ion_type),
Value::Boolean(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::SExpression(sexp) => ivf.format_sexp(sexp),
Value::List(list) => ivf.format_list(list),
}
.map_err(|_| std::fmt::Error)?;

Expand Down
28 changes: 28 additions & 0 deletions tests/element_test_vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,34 @@ fn non_equivs<E: ElementApi>(_element_api: E, file_name: &str) {
});
}

#[cfg(test)]
mod impl_display_for_element_tests {
use super::*;
use ion_rs::value::native_writer::NativeElementWriter;
use ion_rs::value::reader::element_reader;
use ion_rs::{IonResult, TextWriterBuilder};
use std::fs::read;

#[test_resources("ion-tests/iontestdata/good/**/*.ion")]
#[test_resources("ion-tests/iontestdata/good/**/*.10n")]
fn test_to_string(file_name: &str) -> IonResult<()> {
let data = read(file_name)?;
let result = element_reader().read_all(&data)?;

for element in result {
let mut buffer = Vec::with_capacity(2048);
let mut writer = NativeElementWriter::new(TextWriterBuilder::new().build(&mut buffer)?);
writer.write(&element)?;
writer.finish()?;

let expected_string = std::str::from_utf8(buffer.as_slice()).unwrap().to_string();

assert_eq!(element.to_string(), expected_string);
}
Ok(())
}
}

#[cfg(test)]
mod native_element_tests {
use super::*;
Expand Down

0 comments on commit acac4ae

Please sign in to comment.