Skip to content

Commit

Permalink
Adds config option for writing struct field names as text/sid (#816)
Browse files Browse the repository at this point in the history
  • Loading branch information
zslayton authored Aug 17, 2024
1 parent 239d590 commit 4e8739f
Show file tree
Hide file tree
Showing 13 changed files with 334 additions and 128 deletions.
6 changes: 5 additions & 1 deletion src/lazy/encoder/binary/v1_0/container_writers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::lazy::encoder::value_writer::{SequenceWriter, StructWriter};
use crate::lazy::encoder::write_as_ion::WriteAsIon;
use crate::raw_symbol_ref::AsRawSymbolRef;
use crate::result::{EncodingError, IonFailure};
use crate::{IonError, IonResult, RawSymbolRef, SymbolId};
use crate::{v1_0, Encoding, IonError, IonResult, RawSymbolRef, SymbolId, ValueWriterConfig};

/// A helper type that holds fields and logic that is common to [`BinaryListWriter_1_0`],
/// [`BinarySExpWriter_1_0`], and [`BinaryStructWriter_1_0`].
Expand Down Expand Up @@ -338,4 +338,8 @@ impl<'value, 'top> StructWriter for BinaryStructWriter_1_0<'value, 'top> {
fn close(self) -> IonResult<()> {
self.container_writer.end()
}

fn config(&self) -> ValueWriterConfig {
v1_0::Binary::default_value_writer_config()
}
}
1 change: 1 addition & 0 deletions src/lazy/encoder/binary/v1_0/value_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ impl<'value, 'top> ValueWriter for BinaryAnnotatedValueWriter_1_0<'value, 'top>
impl AsRef<[u8]> => write_clob,
impl AsRef<[u8]> => write_blob,
);

fn list_writer(self) -> IonResult<Self::ListWriter> {
BinaryListWriter_1_0::new(self.allocator, self.output_buffer)
.with_annotations(self.annotations)
Expand Down
14 changes: 9 additions & 5 deletions src/lazy/encoder/binary/v1_1/container_writers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::lazy::encoder::value_writer::{EExpWriter, SequenceWriter, StructWrite
use crate::lazy::encoder::value_writer_config::ValueWriterConfig;
use crate::lazy::encoder::write_as_ion::WriteAsIon;
use crate::raw_symbol_ref::AsRawSymbolRef;
use crate::{IonResult, UInt};
use crate::{v1_1, Encoding, IonResult, UInt};

/// A helper type that holds fields and logic that is common to [`BinaryListWriter_1_1`],
/// [`BinarySExpWriter_1_1`], and [`BinaryStructWriter_1_1`].
Expand All @@ -23,7 +23,7 @@ pub(crate) struct BinaryContainerWriter_1_1<'value, 'top> {
// An allocator reference that can be shared with nested container writers
allocator: &'top BumpAllocator,
encoder: ContainerEncodingKind<'value, 'top>,
write_options: ValueWriterConfig,
value_writer_config: ValueWriterConfig,
}

enum ContainerEncodingKind<'value, 'top> {
Expand Down Expand Up @@ -69,7 +69,7 @@ impl<'value, 'top> BinaryContainerWriter_1_1<'value, 'top> {
Self {
allocator,
encoder,
write_options,
value_writer_config: write_options,
}
}

Expand All @@ -90,7 +90,7 @@ impl<'value, 'top> BinaryContainerWriter_1_1<'value, 'top> {
Self {
allocator,
encoder,
write_options,
value_writer_config: write_options,
}
}

Expand All @@ -108,7 +108,7 @@ impl<'value, 'top> BinaryContainerWriter_1_1<'value, 'top> {
}

pub fn config(&self) -> ValueWriterConfig {
self.write_options
self.value_writer_config
}

/// Constructs a new [`BinaryValueWriter_1_1`] using this [`BinaryContainerWriter_1_1`]'s
Expand Down Expand Up @@ -390,6 +390,10 @@ impl<'value, 'top> StructWriter for BinaryStructWriter_1_1<'value, 'top> {
}
self.container_writer.end()
}

fn config(&self) -> ValueWriterConfig {
v1_1::Binary::default_value_writer_config()
}
}

pub struct BinaryEExpWriter_1_1<'value, 'top> {
Expand Down
19 changes: 7 additions & 12 deletions src/lazy/encoder/binary/v1_1/value_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ impl<'value, 'top> BinaryValueWriter_1_1<'value, 'top> {
}

pub fn with_inline_symbol_text(mut self) -> Self {
self.value_writer_config = self.value_writer_config.with_delimited_containers();
self.value_writer_config = self
.value_writer_config
.with_symbol_value_encoding(SymbolValueEncoding::WriteAsInlineText);
self
}

Expand Down Expand Up @@ -721,10 +723,6 @@ impl<'value, 'top> ValueWriter for BinaryValueWriter_1_1<'value, 'top> {
type EExpWriter = BinaryEExpWriter_1_1<'value, 'top>;

delegate_value_writer_to_self!();

fn config(&self) -> ValueWriterConfig {
self.config()
}
}

/// Takes a series of `TYPE => METHOD` pairs, generating a function for each that encodes an
Expand All @@ -741,7 +739,7 @@ macro_rules! annotate_and_delegate_1_1 {
let value_writer = $crate::lazy::encoder::binary::v1_1::value_writer::BinaryValueWriter_1_1::new(
self.allocator,
self.buffer,
self.config(),
self.value_writer_config,
);
value_writer.$method(value)?;
Ok(())
Expand Down Expand Up @@ -821,7 +819,7 @@ impl<'value, 'top> AnnotatableWriter for BinaryAnnotatedValueWriter_1_1<'value,
self.allocator,
self.buffer,
annotations.into_annotations_vec(),
self.config(),
self.value_writer_config,
))
}
}
Expand Down Expand Up @@ -868,10 +866,6 @@ impl<'value, 'top> ValueWriter for BinaryAnnotatedValueWriter_1_1<'value, 'top>
}
self.value_writer().eexp_writer(macro_id)
}

fn config(&self) -> ValueWriterConfig {
self.value_writer_config
}
}

impl<'value, 'top> BinaryAnnotatedValueWriter_1_1<'value, 'top> {
Expand All @@ -889,7 +883,8 @@ impl<'value, 'top> BinaryAnnotatedValueWriter_1_1<'value, 'top> {
}
}
pub(crate) fn value_writer(self) -> BinaryValueWriter_1_1<'value, 'top> {
let writer = BinaryValueWriter_1_1::new(self.allocator, self.buffer, self.config());
let writer =
BinaryValueWriter_1_1::new(self.allocator, self.buffer, self.value_writer_config);
writer
}

Expand Down
8 changes: 7 additions & 1 deletion src/lazy/encoder/text/v1_0/value_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ use crate::result::IonFailure;
use crate::text::text_formatter::{FmtValueFormatter, IoValueFormatter};
use crate::text::whitespace_config::WhitespaceConfig;
use crate::types::{ContainerType, ParentType};
use crate::{Decimal, Int, IonResult, IonType, RawSymbolRef, Timestamp};
use crate::{
v1_0, Decimal, Encoding, Int, IonResult, IonType, RawSymbolRef, Timestamp, ValueWriterConfig,
};

pub struct TextValueWriter_1_0<'value, W: Write + 'value> {
pub(crate) writer: &'value mut LazyRawTextWriter_1_0<W>,
Expand Down Expand Up @@ -448,6 +450,10 @@ impl<'value, W: Write> StructWriter for TextStructWriter_1_0<'value, W> {
fn close(self) -> IonResult<()> {
self.end()
}

fn config(&self) -> ValueWriterConfig {
v1_0::Text::default_value_writer_config()
}
}

impl<'value, W: Write + 'value> AnnotatableWriter for TextAnnotatedValueWriter_1_0<'value, W> {
Expand Down
6 changes: 5 additions & 1 deletion src/lazy/encoder/text/v1_1/value_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::lazy::text::raw::v1_1::reader::MacroIdRef;
use crate::raw_symbol_ref::AsRawSymbolRef;
use crate::result::IonFailure;
use crate::types::{ContainerType, ParentType};
use crate::{Decimal, Int, IonResult, IonType, Timestamp};
use crate::{v1_1, Decimal, Encoding, Int, IonResult, IonType, Timestamp, ValueWriterConfig};
use delegate::delegate;
use std::io::Write;

Expand Down Expand Up @@ -230,6 +230,10 @@ impl<'value, W: Write> StructWriter for TextStructWriter_1_1<'value, W> {
fn close(self) -> IonResult<()> {
self.writer_1_0.close()
}

fn config(&self) -> ValueWriterConfig {
v1_1::Text::default_value_writer_config()
}
}

pub struct TextEExpWriter_1_1<'value, W: Write> {
Expand Down
18 changes: 11 additions & 7 deletions src/lazy/encoder/value_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,6 @@ pub trait ValueWriter: AnnotatableWriter + Sized {
strukt.write_all(values)?;
strukt.close()
}

fn config(&self) -> ValueWriterConfig {
ValueWriterConfig::default()
}
}

/// There are several implementations of `ValueWriter` that simply delegate calls to an expression.
Expand Down Expand Up @@ -183,6 +179,7 @@ macro_rules! delegate_value_writer_to {
self,
macro_id: impl Into<MacroIdRef<'a>>,
) -> IonResult<Self::EExpWriter>;

}
}
};
Expand All @@ -204,13 +201,19 @@ pub(crate) use delegate_value_writer_to_self;
pub struct FieldWriter<'field, StructWriterType> {
name: RawSymbolRef<'field>,
struct_writer: &'field mut StructWriterType,
value_writer_config: ValueWriterConfig,
}

impl<'field, StructWriterType> FieldWriter<'field, StructWriterType> {
pub fn new(name: RawSymbolRef<'field>, struct_writer: &'field mut StructWriterType) -> Self {
pub(crate) fn new(
name: RawSymbolRef<'field>,
value_writer_config: ValueWriterConfig,
struct_writer: &'field mut StructWriterType,
) -> Self {
Self {
name,
struct_writer,
value_writer_config,
}
}
}
Expand Down Expand Up @@ -334,10 +337,11 @@ pub trait StructWriter: FieldEncoder + MakeValueWriter + Sized {
}

fn field_writer<'a>(&'a mut self, name: impl Into<RawSymbolRef<'a>>) -> FieldWriter<'a, Self> {
FieldWriter::new(name.into(), self)
FieldWriter::new(name.into(), self.config(), self)
}

fn close(self) -> IonResult<()>;

fn config(&self) -> ValueWriterConfig;
}

/// Takes a series of `TYPE => METHOD` pairs, generating a function for each that calls the
Expand Down
49 changes: 35 additions & 14 deletions src/lazy/encoder/value_writer_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,49 +78,64 @@ pub enum FieldNameEncoding {
}

impl ValueWriterConfig {
/// Constructs a default `ValueWriterConfig`.
pub fn new() -> Self {
ValueWriterConfig::default()
/// Constructs a `ValueWriterConfig` that writes all symbol tokens as inline text.
pub const fn text() -> Self {
ValueWriterConfig {
container_encoding: ContainerEncoding::Delimited,
symbol_value_encoding: SymbolValueEncoding::WriteAsInlineText,
annotations_encoding: AnnotationsEncoding::WriteAsInlineText,
field_name_encoding: FieldNameEncoding::WriteAsInlineText,
}
}

pub fn container_encoding(&self) -> ContainerEncoding {
/// Constructs a `ValueWriterConfig` that writes all symbol tokens as symbol IDs.
pub const fn binary() -> Self {
ValueWriterConfig {
container_encoding: ContainerEncoding::LengthPrefixed,
symbol_value_encoding: SymbolValueEncoding::WriteAsSymbolIds,
annotations_encoding: AnnotationsEncoding::WriteAsSymbolIds,
field_name_encoding: FieldNameEncoding::WriteAsSymbolIds,
}
}

pub const fn container_encoding(&self) -> ContainerEncoding {
self.container_encoding
}

pub fn symbol_value_encoding(&self) -> SymbolValueEncoding {
pub const fn symbol_value_encoding(&self) -> SymbolValueEncoding {
self.symbol_value_encoding
}

pub fn field_name_encoding(&self) -> FieldNameEncoding {
pub const fn field_name_encoding(&self) -> FieldNameEncoding {
self.field_name_encoding
}

pub fn annotations_encoding(&self) -> AnnotationsEncoding {
pub const fn annotations_encoding(&self) -> AnnotationsEncoding {
self.annotations_encoding
}

/// Returns `true` if this value writer will write nested containers with a delimited encoding.
pub fn has_delimited_containers(&self) -> bool {
self.container_encoding == ContainerEncoding::Delimited
pub const fn has_delimited_containers(&self) -> bool {
matches!(self.container_encoding, ContainerEncoding::Delimited)
}

/// Configures this value writer will write nested containers using a delimited encoding. If it
/// is `false`, nested containers will be length-prefixed.
pub fn with_delimited_containers(mut self) -> Self {
pub const fn with_delimited_containers(mut self) -> Self {
self.container_encoding = ContainerEncoding::Delimited;
self
}

/// If `delimited_containers` is `true`, this value writer will write nested containers using
/// a delimited encoding. If it is `false`, nested containers will be length-prefixed.
pub fn with_container_encoding(mut self, container_encoding: ContainerEncoding) -> Self {
pub const fn with_container_encoding(mut self, container_encoding: ContainerEncoding) -> Self {
self.container_encoding = container_encoding;
self
}

/// Configures this value writer to write symbol values and annotations with their UTF-8 text
/// inline.
pub fn with_symbol_value_encoding(
pub const fn with_symbol_value_encoding(
mut self,
symbol_value_encoding: SymbolValueEncoding,
) -> Self {
Expand All @@ -129,14 +144,20 @@ impl ValueWriterConfig {
}

/// Configures how this value writer will encode its annotations (if any).
pub fn with_annotations_encoding(mut self, annotations_encoding: AnnotationsEncoding) -> Self {
pub const fn with_annotations_encoding(
mut self,
annotations_encoding: AnnotationsEncoding,
) -> Self {
self.annotations_encoding = annotations_encoding;
self
}

/// If this value writer is used to write a struct, the struct be configured to encode its
/// field names according to the specified t`field_name_encoding`.
pub fn with_field_name_encoding(mut self, field_name_encoding: FieldNameEncoding) -> Self {
pub const fn with_field_name_encoding(
mut self,
field_name_encoding: FieldNameEncoding,
) -> Self {
self.field_name_encoding = field_name_encoding;
self
}
Expand Down
Loading

0 comments on commit 4e8739f

Please sign in to comment.