ion-rust icon indicating copy to clipboard operation
ion-rust copied to clipboard

Timestamps after roundtripping through encodings have unexpected equality semantics.

Open jpschorr opened this issue 11 months ago • 0 comments

I found this a bit surprising:

#[test]
fn ion_dates() {
    let l = "2000T";
    let r = "2000-01-01T00:00:00.000+00:00";
    let l = ion_rs::Element::read_one(l).expect("read");
    let r = ion_rs::Element::read_one(r).expect("read");

    let reencode_txt = |e: &Element| {
        let encoded = e.encode_as(ion_rs::v1_0::Text).expect("encode");
        ion_rs::Element::read_one(encoded).expect("read")
    };

    let reencode_bin = |e: &Element| {
        let encoded = e.encode_as(ion_rs::v1_0::Binary).expect("encode");
        ion_rs::Element::read_one(encoded).expect("read")
    };

    dbg!(l == r);

    dbg!(reencode_txt(&l) == r);
    dbg!(l == reencode_txt(&r));
    dbg!(reencode_txt(&l) == reencode_txt(&r));

    dbg!(reencode_bin(&l) == r);
    dbg!(l == reencode_bin(&r));
    dbg!(reencode_bin(&l) == reencode_bin(&r));

    dbg!(reencode_txt(&l) == reencode_bin(&r));
    dbg!(reencode_bin(&l) == reencode_txt(&r));
}
[...] l == r = false
[...] reencode_txt(&l) == r = false
[...] l == reencode_txt(&r) = false
[...] reencode_txt(&l) == reencode_txt(&r) = false
[...] reencode_bin(&l) == r = false
[...] l == reencode_bin(&r) = true
[...] reencode_bin(&l) == reencode_bin(&r) = true
[...] reencode_txt(&l) == reencode_bin(&r) = true
[...] reencode_bin(&l) == reencode_txt(&r) = false

I expected all of the above to agree on equality.

It seems like after encoding, it comes back with 0 in Mantissa::Digits, whereas it had 3 before encoding. So fractional_seconds_equal says false

The conversion seems to happen here: https://github.com/amazon-ion/ion-rust/blob/main/src/types/timestamp.rs#L983-L985

jpschorr avatar Jan 30 '25 23:01 jpschorr