-
Notifications
You must be signed in to change notification settings - Fork 36
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
Conversation
There was a problem hiding this 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 |
There was a problem hiding this comment.
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"]} |
There was a problem hiding this comment.
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.)
src/lazy/encoder/binary/mod.rs
Outdated
fn ptr_to_mut_ref<'a, T>(ptr: *mut ()) -> &'a mut T { | ||
let typed_ptr: *mut T = ptr.cast(); | ||
unsafe { &mut *typed_ptr } | ||
} |
There was a problem hiding this comment.
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> {} |
There was a problem hiding this comment.
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.
delegate! { | ||
to self { | ||
fn value_writer(&mut self) -> Self::ValueWriter<'_>; | ||
} |
There was a problem hiding this comment.
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<()> { |
There was a problem hiding this comment.
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.
delegate! { | ||
to self { |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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>; |
There was a problem hiding this comment.
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>>( |
There was a problem hiding this comment.
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.
// 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. |
There was a problem hiding this comment.
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)?
// 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it!
There was a problem hiding this comment.
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.
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 |
There was a problem hiding this comment.
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).
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. |
There was a problem hiding this 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.
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 andion-tests
integration.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.