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

Initial impl of a LazyRawAnyReader #621

Merged
merged 19 commits into from
Aug 23, 2023
Merged

Initial impl of a LazyRawAnyReader #621

merged 19 commits into from
Aug 23, 2023

Conversation

zslayton
Copy link
Contributor

@zslayton zslayton commented Aug 11, 2023

Builds on outstanding PRs #609, #612, #613, #614, #616, #617, #619, and #620.

Adds the LazyRawAnyReader, a LazyDecoder implementation that can read either text or binary Ion.

Because LazyDecoder is a family of types, using it via Box<dyn> would require boxing and dynamic dispatch at multiple levels. This implementation of the LazyRawAnyReader avoids that problem by defining several new types that hold either a text or binary reader in an enum and delegates method calls to the one in use.

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

@codecov
Copy link

codecov bot commented Aug 11, 2023

Codecov Report

Patch coverage: 71.46% and project coverage change: -0.01% ⚠️

Comparison is base (0be49e2) 81.11% compared to head (f603872) 81.11%.

❗ Current head f603872 differs from pull request most recent head 4ccf490. Consider uploading reports for the commit 4ccf490 to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #621      +/-   ##
==========================================
- Coverage   81.11%   81.11%   -0.01%     
==========================================
  Files         123      123              
  Lines       22570    22572       +2     
  Branches    22570    22572       +2     
==========================================
+ Hits        18308    18309       +1     
- Misses       2574     2575       +1     
  Partials     1688     1688              
Files Changed Coverage Δ
src/lazy/binary/raw/reader.rs 76.31% <ø> (ø)
src/lazy/encoding.rs 0.00% <0.00%> (ø)
src/lazy/reader.rs 66.66% <ø> (ø)
src/lazy/sequence.rs 73.07% <ø> (ø)
src/lazy/struct.rs 66.66% <ø> (ø)
src/lazy/value.rs 73.28% <0.00%> (ø)
src/result/decoding_error.rs 42.85% <12.50%> (ø)
src/lazy/system_reader.rs 77.15% <25.00%> (ø)
src/lazy/text/parse_result.rs 25.56% <25.56%> (ø)
src/lazy/text/as_utf8.rs 31.25% <31.25%> (ø)
... and 24 more

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

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

Comment on lines 399 to 404
fn value(&self) -> LazyRawAnyValue<'data> {
match &self.encoding {
LazyRawFieldKind::Text_1_0(f) => f.value().into(),
LazyRawFieldKind::Binary_1_0(f) => f.value().into(),
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ There's a subtle API challenge here.

Prior to this PR, the value() trait method required that implementers return a &D::Value; in the case of AnyEncoding, that would mean returning a &LazyRawAnyValue.

Any time a method returns a &T (not &'static T), there MUST be a T living inside one of the method's parameters. In this case, there would need to be a LazyRawAnyValue living inside self, which there isn't. Instead, self contains the raw materials to construct a LazyRawAnyValue: either a LazyRawTextValue or a LazyRawBinaryValue. We can't return a &LazyRawAnyValue because it's illegal to return a reference to a stack-allocated variable created in this method's scope.

Fortunately, both LazyRawTextValue and LazyRawBinaryValue are eligible to implement Copy. Neither owns any heap-allocated resources. I changed the trait to return a copy of the value instead of a reference to one, resolving this issue. There are minor ripples of this change through the rest of this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now that as_value is returning a copy of the value and not a reference, it should be called to_value. I've captured that in #626 and will address it when the merge queue is empty.

Comment on lines 320 to 329
#[derive(Debug, Clone)]
pub struct LazyRawAnyStruct<'data> {
encoding: LazyRawStructKind<'data>,
}

#[derive(Debug, Clone)]
pub enum LazyRawStructKind<'data> {
Text_1_0(LazyRawTextStruct<'data>),
Binary_1_0(LazyRawBinaryStruct<'data>),
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these LazyRawAny* structs exposed to users of the crate, or are they just pub in this module? If just pub in this module, is there any reason these can't be collapsed to remove the extra layer of indirection? (And similarly for the other struct/enum combos.)

Suggested change
#[derive(Debug, Clone)]
pub struct LazyRawAnyStruct<'data> {
encoding: LazyRawStructKind<'data>,
}
#[derive(Debug, Clone)]
pub enum LazyRawStructKind<'data> {
Text_1_0(LazyRawTextStruct<'data>),
Binary_1_0(LazyRawBinaryStruct<'data>),
}
#[derive(Debug, Clone)]
pub struct LazyRawAnyStruct<'data> {
Text_1_0(LazyRawTextStruct<'data>),
Binary_1_0(LazyRawBinaryStruct<'data>),
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Offline discussion—the structs will eventually be public.

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 plan is for the structs to be pub, but the enums to be hidden. That way they don't have to be marked non_exhaustive and we can add other formats/versions over time.

Base automatically changed from lazy-ivm to main August 23, 2023 03:37
@zslayton zslayton merged commit ea1b61c into main Aug 23, 2023
16 checks passed
@zslayton zslayton deleted the lazy-any-reader branch August 23, 2023 19:50
@zslayton zslayton self-assigned this Aug 29, 2023
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