Comments (4)
Thanks for the report @zheland. I think we've got two options here:
- Enshrine the panic by making it explicit (not just debug) and add a section to the docs.
- Truncate the timestamp so those before the epoch will be set to the epoch, along with a section in the docs.
Do either of those options appeal to you more than the other?
from uuid.
- I don't like panic variant. I do not think that generating UUID with a time value smaller than unix epoch is a good reason for a panic. It seems to me that such things should be forgiven quietly in most UUID generation usecases.
- Truncating seems much better to me, but with an incorrect time value it may result in a very similar generated UUIDs for
UUIDv1
andUUIDv6
. However, if considering that the use of incorrect time is rather wrong, then this option is basically completely fine. - Alternatively, I might suggest using wrapping operations when converting between rfc4122 and unix time. This will make it possible to obtain some unix time value from any rfc4122. And if necessary convert it back to the same rfc4122 timestamp.
Pros:UUIDv1
will support any valid rfc4122 timestamp andUUIDv7
will support any valid unix timestamp.
Cons: Possible silent wrapping operations when using invalid unix time to generateUUIDv1
or silent wrapping operations when using invalid rfc4122 to generateUUIDv7
. If mentioned in the documentation it looks quite tolerable behavior.
// draft example, I have not checked the implementation in detail
pub const UUID_TICKS_BETWEEN_EPOCHS: u64 = 0x01B2_1DD2_1381_4000;
pub const UUID_SECS_BETWEEN_EPOCHS: u64 = UUID_TICKS_BETWEEN_EPOCHS / 10_000_000;
const fn unix_to_rfc4122_ticks(seconds: u64, nanos: u32) -> u64 {
seconds
.wrapping_add(UUID_SECS_BETWEEN_EPOCHS)
.wrapping_mul(10_000_000)
.wrapping_add(nanos as u64 / 100)
}
const fn rfc4122_to_unix(ticks: u64) -> (u64, u32) {
(
(ticks / 10_000_000).wrapping_sub(UUID_SECS_BETWEEN_EPOCHS),
(ticks % 10_000_000) as u32 * 100,
)
}
#[test]
fn any_rfc4122_can_be_mapped_to_the_corresponding_unixtime_and_back() {
for (rfc4122, unix) in [
(u64::MAX, (0x0000_01AA_A6D6_0F4A, 955_161_500)),
(u64::MAX / 2 + 1, (0x0000_00D3_E741_3965, 477_580_800)),
(UUID_TICKS_BETWEEN_EPOCHS, (0, 0)),
(UUID_TICKS_BETWEEN_EPOCHS - 1, (u64::MAX, 999_999_900)),
(10_000_000, (0xFFFF_FFFD_27AC_6381, 0)),
(1, (0xFFFF_FFFD_27AC_6380, 100)),
(0, (0xFFFF_FFFD_27AC_6380, 0)),
] {
assert_eq!(rfc4122_to_unix(rfc4122), unix);
assert_eq!(unix_to_rfc4122_ticks(unix.0, unix.1), rfc4122);
}
}
#[test]
fn not_any_unixtime_can_be_mapped_to_the_corresponding_rfc4122() {
assert_eq!(unix_to_rfc4122_ticks(0, 0), UUID_TICKS_BETWEEN_EPOCHS);
assert_eq!(unix_to_rfc4122_ticks(0, 99), UUID_TICKS_BETWEEN_EPOCHS);
assert_eq!(
unix_to_rfc4122_ticks(0xFE00_0000_0000_0000, 0),
UUID_TICKS_BETWEEN_EPOCHS
);
}
from uuid.
I’m also more inclined to a non-panicking variant here. For anybody that’s concerned about quietly changing behaviour through wrapping or truncation we can offer a checked_from_rfc4122
that returns an Option
.
I do like that the wrapping variant gives you a more uniquely useful timestamp. I’d be happy with an implementation that did that. It might also be worth checking the current draft spec that introduces v6-v8 and see if it recommends any behaviour converting RRC4122 timestamps to Unix time.
from uuid.
Thanks @zheland 👍 I've opened #691 that addresses this by explicitly wrapping, basically as you've suggested here. All we're guaranteeing is that those methods won't panic, not that they'll wrap to any particular value, so I've reflected that in the test by only ensuring overflowing inputs don't panic.
from uuid.
Related Issues (20)
- 1.3.4 and 1.3.3 failing in Cloudflare Worker env for different reasons
- Unable to activate feature "v7" HOT 6
- Request: add configuration to enable/disable deserializing different formats HOT 2
- Wrapping behavior of `impl ClockSequence for Context` HOT 4
- Export `error::InvalidUuid` HOT 2
- Make &'a Uuid serializable HOT 3
- UUID no longer supports serde derive attributes HOT 2
- Add bytemuck support HOT 1
- Add `prost::Message` implementation for `Uuid` HOT 3
- v7 should have a counter option? HOT 36
- Macros from 1.5.0 to 1.6.0 break. HOT 4
- Investigate crate size HOT 2
- Idiotmatic naming: drop/replace `get_` prefixes HOT 4
- 1.7.0 breaking change HOT 2
- Initialization of CONTEXT in timestamp::context::shared_context() not thread-safe HOT 1
- the trait Deserialize is not implemented for `Uuid` HOT 2
- TryFrom<Vec<u8>> makes an unnecessary copy HOT 1
- `uuid!` `index is out of bounds` in clippy on rust 1.77 (fixed in uuid 1.6.1)
- Why does Uuid implement Ord, PartialOrd? HOT 1
- uuid!() macro can't handle a constant &str passed in HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from uuid.