summaryrefslogtreecommitdiffstats
path: root/crates/core/tedge_api/src/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/core/tedge_api/src/util.rs')
-rw-r--r--crates/core/tedge_api/src/util.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/crates/core/tedge_api/src/util.rs b/crates/core/tedge_api/src/util.rs
new file mode 100644
index 00000000..ebd0fbf1
--- /dev/null
+++ b/crates/core/tedge_api/src/util.rs
@@ -0,0 +1,36 @@
+//! Utilities
+
+/// Generates a new UUID from the given UUIDs `a` and `b`,
+/// where the bytes are generated by a bitwise `a ^ b.rotate_right(1)`.
+/// The generated UUID will be a `UUIDv4` (meaning that the bytes should be random, not e.g. derived from the system time).
+///
+/// # Note
+///
+/// Vendored from https://github.com/bevyengine/bevy/commit/3d36ec41dcbfe7d5ead2a9dc5777c933f7f37e09
+/// because the change was not released at the time of implementing the TypeUuid functionality.
+///
+/// Should be removed as soon as bevy_reflect 0.8.0 is released
+#[allow(clippy::unusual_byte_groupings)] // unusual byte grouping is meant to signal the relevant bits
+pub const fn generate_composite_uuid(
+ a: bevy_reflect::Uuid,
+ b: bevy_reflect::Uuid,
+) -> bevy_reflect::Uuid {
+ let mut new = [0; 16];
+ let mut i = 0;
+ while i < new.len() {
+ // rotating ensures different uuids for A<B<C>> and B<A<C>> because: A ^ (B ^ C) = B ^ (A ^ C)
+ // notice that you have to rotate the second parameter: A.rr ^ (B.rr ^ C) = B.rr ^ (A.rr ^ C)
+ // Solution: A ^ (B ^ C.rr).rr != B ^ (A ^ C.rr).rr
+ new[i] = a.as_bytes()[i] ^ b.as_bytes()[i].rotate_right(1);
+
+ i += 1;
+ }
+
+ // Version: the most significant 4 bits in the 6th byte: 11110000
+ new[6] = new[6] & 0b0000_1111 | 0b0100_0000; // set version to v4
+
+ // Variant: the most significant 3 bits in the 8th byte: 11100000
+ new[8] = new[8] & 0b000_11111 | 0b100_00000; // set variant to rfc4122
+
+ bevy_reflect::Uuid::from_bytes(new)
+}