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

Modifies the serde serializer to use the new writer #747

Merged
merged 2 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions src/binary/raw_binary_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::ion_writer::IonWriter;
use crate::raw_symbol_token_ref::{AsRawSymbolTokenRef, RawSymbolTokenRef};
use crate::result::{IonFailure, IonResult};
use crate::types::integer::IntData;
use crate::types::ContainerType;
use crate::types::ParentType;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ The ContainerType enum defined in types/mod.rs was renamed to ParentType because it also includes a TopLevel variant. Another ContainerType was also created that is limited to only containers:

enum ContainerType {
  List,
  SExp,
  Struct, 
}

enum ParentType {
  TopLevel,
  List,
  SExp,
  Struct,
}

Copy link
Contributor

Choose a reason for hiding this comment

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

It's IonDatagram all over again! 😉

use crate::{Decimal, Int, IonType, SymbolId, Timestamp};

use super::decimal::DecimalBinaryEncoder;
Expand All @@ -34,7 +34,7 @@ impl RawBinaryWriterBuilder {
pub fn build<W: Write>(self, out: W) -> IonResult<RawBinaryWriter<W>> {
let mut levels = Vec::with_capacity(INITIAL_ENCODING_LEVELS_CAPACITY);
// Create an EncodingLevel to represent the top level. It has no annotations.
levels.push(EncodingLevel::new(ContainerType::TopLevel, None, 0, 0));
levels.push(EncodingLevel::new(ParentType::TopLevel, None, 0, 0));
// Create an empty IoRange for top-level leading scalar values.
let mut io_ranges = Vec::with_capacity(INITIAL_IO_RANGE_CAPACITY);
io_ranges.push(0usize..0);
Expand Down Expand Up @@ -105,7 +105,7 @@ type IoRange = Range<usize>;
// annotations, field_id, and container type.
#[derive(Debug)]
struct EncodingLevel {
container_type: ContainerType,
container_type: ParentType,
field_id: Option<SymbolId>,
// Annotations are stored in a common Vec on the BinarySystemWriter. Each EncodingLevel tracks
// how many annotations it had, allowing that Vec to be treated as a stack. Stepping into
Expand All @@ -119,7 +119,7 @@ struct EncodingLevel {

impl EncodingLevel {
fn new(
container_type: ContainerType,
container_type: ParentType,
field_id: Option<SymbolId>,
num_annotations: u8,
td_io_range_index: usize,
Expand Down Expand Up @@ -205,7 +205,7 @@ impl<W: Write> RawBinaryWriter<W> {
fn is_in_struct(&self) -> bool {
self.levels
.last()
.map(|level| level.container_type == ContainerType::Struct)
.map(|level| level.container_type == ParentType::Struct)
.unwrap_or(false)
}

Expand Down Expand Up @@ -729,9 +729,9 @@ impl<W: Write> IonWriter for RawBinaryWriter<W> {
fn step_in(&mut self, ion_type: IonType) -> IonResult<()> {
use IonType::*;
let container_type = match ion_type {
List => ContainerType::List,
SExp => ContainerType::SExpression,
Struct => ContainerType::Struct,
List => ParentType::List,
SExp => ParentType::SExp,
Struct => ParentType::Struct,
_ => return IonResult::illegal_operation("Cannot step into a scalar Ion type."),
};

Expand Down Expand Up @@ -785,10 +785,10 @@ impl<W: Write> IonWriter for RawBinaryWriter<W> {
// `self.levels` always has at least one value: the top level.
// This means we can `unwrap()` the last value safely.
match self.levels.last().unwrap().container_type {
ContainerType::TopLevel => None,
ContainerType::Struct => Some(IonType::Struct),
ContainerType::List => Some(IonType::List),
ContainerType::SExpression => Some(IonType::SExp),
ParentType::TopLevel => None,
ParentType::Struct => Some(IonType::Struct),
ParentType::List => Some(IonType::List),
ParentType::SExp => Some(IonType::SExp),
}
}

Expand All @@ -810,10 +810,10 @@ impl<W: Write> IonWriter for RawBinaryWriter<W> {
self.field_id = container.field_id;
let container_size = container.calculate_final_size(&mut self.io_ranges);

use crate::types::ContainerType::*;
use crate::types::ParentType::*;
let mut type_descriptor: u8 = match container.container_type {
List => 0xB0,
SExpression => 0xC0,
SExp => 0xC0,
Struct => 0xD0,
_ => return IonResult::illegal_operation("Cannot step into a scalar Ion type."),
};
Expand Down
2 changes: 1 addition & 1 deletion src/element/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub(crate) enum WriteConfigKind {
/// Text writer configuration with text kind to be used to create a writer
#[derive(Clone, Debug)]
pub(crate) struct TextWriteConfig {
text_kind: TextKind,
pub(crate) text_kind: TextKind,
}

/// Binary writer configuration to be used to create a writer
Expand Down
25 changes: 17 additions & 8 deletions src/lazy/encoder/text/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use crate::lazy::encoder::value_writer::SequenceWriter;
use crate::lazy::encoder::write_as_ion::WriteAsIon;
use crate::lazy::encoder::{LazyEncoder, LazyRawWriter, SymbolCreationPolicy};
use crate::lazy::encoding::{Encoding, TextEncoding_1_0};
use crate::text::raw_text_writer::{WhitespaceConfig, PRETTY_WHITESPACE_CONFIG};
use crate::text::raw_text_writer::{
WhitespaceConfig, COMPACT_WHITESPACE_CONFIG, LINES_WHITESPACE_CONFIG, PRETTY_WHITESPACE_CONFIG,
};
use crate::types::ParentType;
use crate::{IonResult, TextKind};
use delegate::delegate;
use std::io::Write;
Expand All @@ -30,11 +33,6 @@ impl<W: Write> LazyRawTextWriter_1_0<W> {
/// Writes the provided data as a top-level value.
pub fn write<V: WriteAsIon>(&mut self, value: V) -> IonResult<&mut Self> {
value.write_as_ion(self.value_writer())?;
write!(
self.output,
"{}",
self.whitespace_config.space_between_top_level_values
)?;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ This ended up being redundant with whitespace printing handled by the TextValueWriter_1_0.

Ok(self)
}

Expand All @@ -50,7 +48,8 @@ impl<W: Write> LazyRawTextWriter_1_0<W> {
TextValueWriter_1_0::new(
self,
0,
self.whitespace_config.space_between_top_level_values,
"", // No delimiter between values at the top level
Comment on lines -53 to +51
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm missing something here. I don't see how the other changes allow us to have no delimiter between top level values here. I also don't know why the parent type here is TopLevel. I thought this is the top level writer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm missing something here. I don't see how the other changes allow us to have no delimiter between top level values here.

This code was adding a single space between top level values, but the parameter was actually expecting the caller to provide a delimiter between values -- , for list/struct, or the empty string for sexp/top-level. Doing both resulted in too much whitespace in the output; not invalid, but not we wanted.

I also don't know why the parent type here is TopLevel.

Each parent type (top level, list, sexp, struct) can construct a *ValueWriter that will encode the provided value into that context. Because this value writer is being created by the LazyRawTextWriter_1_0 (and not by a container writer), it is going to write the value it encodes into the top level. Thus, the value's parent is the top level.

ParentType::TopLevel,
)
}
}
Expand Down Expand Up @@ -82,7 +81,17 @@ impl<W: Write> LazyRawWriter<W> for LazyRawTextWriter_1_0<W> {
/// Build text writer based on given writer configuration
fn build<E: Encoding>(config: WriteConfig<E>, output: W) -> IonResult<Self> {
match &config.kind {
WriteConfigKind::Text(_) => Ok(LazyRawTextWriter_1_0::new(output)),
WriteConfigKind::Text(text_config) => {
let whitespace_config = match text_config.text_kind {
TextKind::Compact => &COMPACT_WHITESPACE_CONFIG,
TextKind::Lines => &LINES_WHITESPACE_CONFIG,
TextKind::Pretty => &PRETTY_WHITESPACE_CONFIG,
};
Ok(LazyRawTextWriter_1_0 {
output,
whitespace_config,
})
}
Comment on lines +84 to +94
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ The LazyRawTextWriter_1_0 now takes the configuration's specified TextKind into account.

WriteConfigKind::Binary(_) => {
unreachable!("Binary writer can not be created from text encoding")
}
Expand Down
Loading
Loading