Skip to content

Commit

Permalink
Adds write_value to ElementWriter
Browse files Browse the repository at this point in the history
  • Loading branch information
popematt committed Jun 28, 2023
1 parent 247ac34 commit e27cad9
Showing 1 changed file with 54 additions and 6 deletions.
60 changes: 54 additions & 6 deletions src/element/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@ pub use TextKind::*;

/// Serializes [`Element`] instances into some kind of output sink.
pub trait ElementWriter {
/// Serializes a single [`Element`] as a top-level value.
/// Serializes a single [`Element`] at the current depth of the writer.
fn write_element(&mut self, element: &Element) -> IonResult<()>;

/// Serializes a collection of [`Element`] as a series of top-level values.
/// Serializes a single [`Value`] at the current depth of the writer.
// TODO: consider extracting this to a ValueWriter trait.
fn write_value(&mut self, value: &Value) -> IonResult<()>;

/// Serializes a collection of [`Element`].
///
/// Most commonly used to serialize a series of top-level values, but can be used to write
/// [`Element`]s to an Ion `list` or `sexp` as well.
///
/// This will return [`Err`] if writing any element causes a failure.
fn write_elements<'a, I: IntoIterator<Item = &'a Element>>(
Expand All @@ -35,8 +42,11 @@ where
{
fn write_element(&mut self, element: &Element) -> IonResult<()> {
self.set_annotations(element.annotations());
self.write_value(element.value())
}

match element.value() {
fn write_value(&mut self, value: &Value) -> IonResult<()> {
match value {
Value::Null(ion_type) => self.write_null(*ion_type),
Value::Int(i) => self.write_int(i),
Value::Float(f) => {
Expand Down Expand Up @@ -96,11 +106,11 @@ pub enum Format {
#[cfg(test)]
mod tests {
use crate::element::writer::ElementWriter;
use crate::element::Element;
use crate::element::{Element, List};
use crate::ion_data::IonEq;
use crate::text::text_writer::TextWriterBuilder;

use crate::{IonResult, IonWriter};
use crate::{IonResult, IonType, IonWriter};
use nom::AsBytes;

#[test]
Expand All @@ -109,7 +119,7 @@ mod tests {
let mut writer = TextWriterBuilder::default().build(&mut buffer)?;

let ion = r#"
null true 0 1e0 2.0 2022T foo "bar" (foo bar baz) [foo, bar, baz] {foo: true, bar: false}
null true 0 1e0 2.0 2022T foo "bar" (foo bar baz) [foo, bar, baz] {foo: true, bar: false} annotated::value
"#;
let expected_elements = Element::read_all(ion.as_bytes())?;
writer.write_elements(&expected_elements)?;
Expand All @@ -118,4 +128,42 @@ mod tests {
assert!(expected_elements.ion_eq(&actual_elements));
Ok(())
}

#[test]
fn write_nested_element() -> IonResult<()> {
let mut buffer = Vec::new();
let mut writer = TextWriterBuilder::default().build(&mut buffer)?;

let ion = r#"
null true 0 1e0 2.0 2022T foo "bar" (foo bar baz) [foo, bar, baz] {foo: true, bar: false} annotated::value
"#;
let expected_list_elements = Element::read_all(ion.as_bytes())?;
writer.step_in(IonType::List)?;
writer.write_elements(&expected_list_elements)?;
writer.step_out()?;
writer.flush()?;
// This should be an Ion List containing all of the above elements.
let actual_list = Element::read_one(writer.output().as_bytes())?;
let expected_list: Element = List::from(expected_list_elements).into();
assert!(expected_list.ion_eq(&actual_list));
Ok(())
}

#[test]
fn write_value() -> IonResult<()> {
let mut buffer = Vec::new();
let mut writer = TextWriterBuilder::default().build(&mut buffer)?;

let ion = r#"
null true 0 1e0 2.0 2022T foo "bar" (foo bar baz) [foo, bar, baz] {foo: true, bar: false}
"#;
let expected_elements = Element::read_all(ion.as_bytes())?;
for e in &expected_elements {
writer.write_value(e.value())?;
}
writer.flush()?;
let actual_elements = Element::read_all(writer.output().as_bytes())?;
assert!(expected_elements.ion_eq(&actual_elements));
Ok(())
}
}

0 comments on commit e27cad9

Please sign in to comment.