-
Notifications
You must be signed in to change notification settings - Fork 33
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
Adds IonData wrapper that uses Ion equivalence for equality #517
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #517 +/- ##
==========================================
+ Coverage 89.07% 89.33% +0.25%
==========================================
Files 82 84 +2
Lines 13027 13256 +229
==========================================
+ Hits 11604 11842 +238
+ Misses 1423 1414 -9
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report in Codecov by Sentry. |
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.
A couple questions below, but overall I am good.
impl<T: IonEq> From<T> for IonData<T> { | ||
fn from(value: T) -> Self { | ||
IonData(value) | ||
} | ||
} |
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.
@almann, it's here.
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.
🚢 LGTM!
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.
LGTM, but one request regarding doc comments below.
… IonOrd for borrowed values
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.
Overall, I am happy with where this is going, however I am a bit puzzled by the added Bool
/Float
wrappers. I think if this is needed to hide IonEq
we may want to reconsider doing this.
src/element/mod.rs
Outdated
(Int(this), Int(that)) => this.ion_eq(that), | ||
(Float(this), Float(that)) => this.ion_eq(that), | ||
(Float(this), Float(that)) => float::Float::ion_eq_f64(this, that), |
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 is curious, probably worth a comment indicating why this is needed.
src/ion_data/ion_eq.rs
Outdated
impl IonEq for bool { | ||
impl<R: Deref> IonEq for R | ||
where | ||
<R as Deref>::Target: IonEq, |
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 have a slight preference for this kind of formulation, but this is totally subjective.
impl<E, R> IonEq for R where
E: IonEq,
R: Deref<Target = 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.
Actually, there is a difference here, and it causes an error when I change it. Here's a minimum reproducible case:
// Assuming we're using
// impl<E, R> IonEq for R where E: IonEq, R: Deref<Target = E> { ... }
#[test]
fn foo() {
let element_vec: Vec<Element> = Element::read_all("foo 1 true").unwrap();
bar(element_vec.into());
}
fn bar<T: IonEq>(ion: IonData<T>) {
// Do something
}
Fails with:
error[E0277]: the size for values of type `[element::Element]` cannot be known at compilation time
I'm assuming that this is because the trait impl is monomorphized differently depending on how the signature is formulated. (While rearranging a where
clause shouldn't do something like this, in this case we have added a second type parameter and we have changed how Deref::Target
is specified.)
Do you have any insight or theory on the details of why this occurs?
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.
Aha... it needs ?Sized
:
impl<E, R> IonEq for R where
E: IonEq + ?Sized,
R: Deref<Target = 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.
I ended up sticking with my original factoring because it minimizes the number of type parameters, though I cleaned it up by getting rid of some redundant parts.
impl<R: Deref> IonEq for R
where
R::Target: IonEq,
src/ion_data/ion_eq.rs
Outdated
} | ||
// For all other values, fall back to mathematical equivalence | ||
self == other | ||
<Self as Deref>::Target::ion_eq(self, other) |
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.
With my above declaration I think you can write this as:
E::ion_eq(self, other)
src/ion_data/ion_ord.rs
Outdated
impl<R: Deref> IonOrd for R | ||
where | ||
<R as Deref>::Target: IonOrd, | ||
{ | ||
fn ion_cmp(&self, other: &Self) -> Ordering { | ||
T::ion_cmp(self, other) | ||
<Self as Deref>::Target::ion_cmp(self, other) |
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.
Ditto for above.
Hopefully this is good to go now. Latest commit includes:
|
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.
LGTM
Issue #, if available:
None
Description of changes:
IonData
, a struct that can wrap anything that implementsIonEq
.IonData<Element>
, I added some delegations toElement
I thought would be required for it to be useful. There's theread_*()
functions andannotations()
, andvalue()
.IonOrd
, a trait for a total ordering that is consistent withIonEq
.IonOrd
forElement
,Value
, and others.IonEq
fromsrc/
tosrc/ion_data/
so that all of the Ion-data-model-semantics stuff is in one place.PartialOrd
andOrd
toBytes
Element.ion_type()
implementation toValue
;Element.ion_type()
now delegates toValue.ion_type()
IntoIterator
impl for&'a Sequence
I have no illusions that this is perfect, but I want to get something started because we need this for handling things like distinct elements efficiently in
ion-schema-rust
.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.