-
Notifications
You must be signed in to change notification settings - Fork 259
Support Timestamp and Duration types #434
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
Conversation
This PR adds the common Timestamp and Duration types to Uniffi, before I proceed any further there were a few open questions I wanted to discuss:
|
Thanks for this PR. This looks reasonable to me, and the fact that Python is going to lose nanoseconds doesn't seem that much of a big deal to me. However, for various reasons the people who are best suited to dig in to this aren't going to be fully available for a couple of weeks, so please don't see any delays here as representing a lack of interest! |
@mhammond do you think it would be acceptable to leave the Gecko bindings unimplemented in this PR? It doesn't seem like we have standardized on testing in the examples like we have with Swift, Kotlin, and Python, which make me a bit wary about implementing. |
Yes, I think that would be fine. |
5521811
to
3b9e5cf
Compare
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.
@npars thanks for diving in! This is a really well executed PR. I've left detailed comments below, but in summary, the "request" changes here is mainly for:
- Please consider moving the test coverage from
./examples
to./fixtures
. - I think at least the Kotlin code needs to be more careful around handling negative durations.
Also, a broader thought that I figured I'd share....some experimenting suggests that Rust is quite happy to represent SystemTime
instances that are before the unix epoch. Given that all three of the target languages here require code to explicitly disallow pre-epoch times, I wonder if it's worth doing the opposite and explicitly supporting them, making the Rust code a bit more complicated but the code in each of the binding languages a bit simpler.
For example, we might serialize a timestamp
as a signed number of seconds and unsigned nanoseconds, then in the rust code, check for positive or negative duration and calculate the resulting SystemTime
via UNIX_EPOCH + duration
or UNIX_EPOCH - duration
as appropriate.
What do you think?
uniffi_bindgen/src/bindings/swift/templates/RustBufferHelper.swift
Outdated
Show resolved
Hide resolved
That's a good catch, I mistakenly made an assumption based on the Rust std::time::UNIX_EPOCH + Duration::from_secs(i64::MAX as u64) As a side note, it looks like there is an existing issue around this behaviour. I think it makes sense to support pre-epoch times. That change will still leave us with positive only |
Agreed, I don't think there's much we can do about that for |
@rfk I think I've addressed all of your comments. There's probably some room for optimization in the conversion code for each language, but I think it's ok for a first pass. |
- Implement Timestamp and Duration types - For Rust, map Timestamp to Rust SystemTime type and Duration to Rust Duration type - For Kotlin, map Timestamp to Java Instant type and Duration to Java Duration type - For Python, map Timestamp to naive Python datetime type and Duration to Python timedelta type
- Add Timestamp and Duration support to Swift bindings - Add simple test for Timestamp and Duration Swift bindings
- Move time tests to fixtures directory - Remove redundant uniffi.toml from time fixture
This could be said about many things in the current state of this repo, I don't think it will be a blocker for merge 👍🏻 |
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.
Looks great, thank you!
I left a couple of requests for more comments below, and one place where I think the name of a variable is misleading, but otherwise this is in really good shape. I'm going to tick "approve" here because I don't need to look at this again in any detail, please just adjust for those small comments and let me know when it's pushed, and I'll go ahead and merge.
uniffi_bindgen/src/bindings/swift/templates/RustBufferHelper.swift
Outdated
Show resolved
Hide resolved
uniffi_bindgen/src/bindings/swift/templates/RustBufferHelper.swift
Outdated
Show resolved
Hide resolved
uniffi_bindgen/src/bindings/swift/templates/RustBufferHelper.swift
Outdated
Show resolved
Hide resolved
- Fix outdated timestamp description in book - Add documentation around timestamp calculation - Simplify Swift timestamp calculation for pre-epoch times
} | ||
} | ||
|
||
fileprivate func write(into buf: Writer) { | ||
var delta = self.timeIntervalSince1970 | ||
var sign: Int64 = 1 | ||
if delta < 0 { | ||
// The nanoseconds portion of the epoch offset must always be | ||
// positive, to simplify the calculation we will use the absolute | ||
// value of the offset. |
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.
👍🏻
/// offset should be combined with the nanosecond portion. This is because | ||
/// the sign of the seconds portion represents the direction of the offset | ||
/// overall. The sign of the seconds portion can then be used to determine | ||
/// if the total offset should be added to or subtracted from the unix epoch. |
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.
Perfect, thanks so much for adding these!
Duration type
Duration type
to Python timedelta type
Implement bindings for Gecko