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

Binary 1.0 impl for new writer API #686

Merged
merged 6 commits into from
Dec 20, 2023
Merged

Binary 1.0 impl for new writer API #686

merged 6 commits into from
Dec 20, 2023

Conversation

zslayton
Copy link
Contributor

@zslayton zslayton commented Dec 8, 2023

Provides a binary 1.0 implementation of the LazyEncoder family of traits. The second commit is entirely refactoring moves, so reviewers should focus on the first commit's diff. A future PR will add a managed writer wrapper and ion-tests integration.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Copy link
Contributor Author

@zslayton zslayton left a comment

Choose a reason for hiding this comment

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

🗺️ PR tour


/// Associates a value to serialize with a sequence of annotations.
pub struct Annotated<'a, T: ?Sized, A> {
value: &'a T,
annotations: &'a [A],
}

/// Provides implementors with an extension method ([`annotate`](Annotate::annotate)) that allows
/// Provides implementors with an extension method ([`annotate`](Annotate::annotated_with)) that allows
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ Renamed annotate to annotated_with to address #681.

@@ -71,7 +71,7 @@ num-integer = "0.1.44"
num-traits = "0.2"
arrayvec = "0.7"
smallvec = {version ="1.9.0", features = ["const_generics"]}
bumpalo = {version = "3.13.0", features = ["collections"]}
bumpalo = {version = "3.14.0", features = ["collections", "std"]}
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 std feature supplies an implementation of std::io::Write for bumpalo's Vec type. (Aliased to BumpVec in this codebase.)

Comment on lines 62 to 65
fn ptr_to_mut_ref<'a, T>(ptr: *mut ()) -> &'a mut T {
let typed_ptr: *mut T = ptr.cast();
unsafe { &mut *typed_ptr }
}
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've marked this function unsafe in a commit I'll push shortly.

}
}

impl<W: Write> Sealed for LazyRawBinaryWriter_1_0<W> {}
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 dependency on the Sealed trait limits implementations of LazyRawWriter to types within the crate. We can relax this later as needed.

Comment on lines +145 to +148
delegate! {
to self {
fn value_writer(&mut self) -> Self::ValueWriter<'_>;
}
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 use delegate! doesn't save much code, but it does convey the intent nicely.

self.encoding_buffer.as_slice()
}

pub fn write_symbol_id(mut self, symbol_id: SymbolId) -> IonResult<()> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ All of the scalar encoding logic was copy/pasted from the old raw binary writer.

Comment on lines +307 to +308
delegate! {
to self {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ Having the methods live on the type (not the trait) and then having the trait methods delegate to the inherent methods means that you can use the type itself without needing to import the trait.

@@ -1,17 +1,17 @@
#![allow(non_camel_case_types)]

pub mod annotate;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ All of the deletions in this file were actually just moves to another module.

&mut self,
name: A,
value: V,
) -> IonResult<&mut Self>;
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 trait needs to also offer write_null(name, value), write_bool(name, value), etc. Tracking this in #687.

pub trait WriteAsIon {
fn write_as_ion<'a, W: Write + 'a, E: LazyEncoder<W>, V: AnnotatedValueWriter<'a, W, E>>(
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 LazyEncoder trait got simplified a lot in this PR. It only has a single associated type now: Writer<W>. As a result, a lot of these generics and lifetimes could be removed.

@zslayton zslayton marked this pull request as ready for review December 8, 2023 16:35
Comment on lines +27 to +28
// The largest possible 'L' (length) value that can be written directly in a type descriptor byte.
// Larger length values will need to be written as a VarUInt following the type descriptor.
Copy link
Contributor

Choose a reason for hiding this comment

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

minor nitpick—could this be a doc comment (so that it shows up in IDEs)?

src/lazy/encoder/binary/value_writer.rs Show resolved Hide resolved
src/lazy/encoder/binary/value_writer.rs Show resolved Hide resolved
src/lazy/encoder/binary/value_writer.rs Show resolved Hide resolved
src/lazy/encoder/binary/value_writer.rs Show resolved Hide resolved
src/lazy/encoder/value_writer.rs Show resolved Hide resolved
src/lazy/encoder/value_writer.rs Outdated Show resolved Hide resolved
Comment on lines +168 to +173
// XXX: For now, it's not possible to offer versions of `write_list`, `write_sexp`, or
// `write_struct`. This is due to a point-in-time limitation in the borrow checker[1].
// It is still possible to call (e.g.)
// self.value_writer().list_writer(...)
// as a workaround.
// [1]: https://blog.rust-lang.org/2022/10/28/gats-stabilization.html#implied-static-requirement-from-higher-ranked-trait-bounds
Copy link
Contributor

Choose a reason for hiding this comment

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

So, I had an idea since this note isn't very discoverable by users. We could add a no-op implementation of write_list, etc. that has an empty type as one of the function arguments. It's not callable because you can't create an argument to pass to it, but it can hold this note directing users to the workaround. Then, once this limitation is fixed, we can change the argument type of the function to the correct argument type.

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 like it!

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 opened #691 to track this.

src/lazy/encoder/write_as_ion.rs Show resolved Hide resolved
impl_write_as_ion_value_for_iterable!(&[T], T);
impl_write_as_ion_value_for_iterable!([T; N], T, const N: usize);

pub trait WriteAsSExp<T>: Sized
Copy link
Contributor

Choose a reason for hiding this comment

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

I assume this is needed so that you can indicate that an iterable of some sort should be written as a sexp instead of a list (which I assume is the default).

@popematt
Copy link
Contributor

So, I started by reviewing just the first commit, and now that I'm reading the next commits, I see you have already addressed some of the comments I left.

Copy link
Contributor

@popematt popematt left a comment

Choose a reason for hiding this comment

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

Approving because feedback will be addressed in a follow up PR.

@zslayton zslayton merged commit 0d16a73 into main Dec 20, 2023
20 checks passed
@zslayton zslayton deleted the new-binary-writer branch December 20, 2023 12:43
zslayton added a commit that referenced this pull request Dec 21, 2023
zslayton added a commit that referenced this pull request Jan 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants