diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dabf4847..b75d64a2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: Continuous integration env: VERSION_FEATURES: "v1 v3 v4 v5 v6 v7 v8" - DEP_FEATURES: "slog serde arbitrary zerocopy" + DEP_FEATURES: "slog serde arbitrary borsh zerocopy" on: pull_request: diff --git a/Cargo.toml b/Cargo.toml index 8147edeb..a125a754 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ version = "1.3.4" # remember to update html_root_url in lib.rs rustc-args = ["--cfg", "uuid_unstable"] rustdoc-args = ["--cfg", "uuid_unstable"] targets = ["x86_64-unknown-linux-gnu"] -features = ["serde", "arbitrary", "slog", "v1", "v3", "v4", "v5", "v6", "v7", "v8"] +features = ["serde", "arbitrary", "slog", "borsh", "v1", "v3", "v4", "v5", "v6", "v7", "v8"] [package.metadata.playground] features = ["serde", "v1", "v3", "v4", "v5", "v6", "v7", "v8"] @@ -86,6 +86,11 @@ version = "2" optional = true version = "1.1.3" +# Public: Used in trait impls on `Uuid` +[dependencies.borsh] +optional = true +version = "0.10.3" + # Public (unstable): Used in `zerocopy` derive # Unstable: also need RUSTFLAGS="--cfg uuid_unstable" to work # This feature may break between releases, or be removed entirely before diff --git a/src/external.rs b/src/external.rs index 219a9236..6f20d8fd 100644 --- a/src/external.rs +++ b/src/external.rs @@ -1,5 +1,7 @@ #[cfg(feature = "arbitrary")] pub(crate) mod arbitrary_support; +#[cfg(feature = "borsh")] +pub(crate) mod borsh_support; #[cfg(feature = "serde")] pub(crate) mod serde_support; #[cfg(feature = "slog")] diff --git a/src/external/borsh_support.rs b/src/external/borsh_support.rs new file mode 100644 index 00000000..2143838b --- /dev/null +++ b/src/external/borsh_support.rs @@ -0,0 +1,41 @@ +use crate::Uuid; +use std::io::{Read, Result, Write}; +use borsh::{BorshDeserialize, BorshSerialize}; + +impl BorshSerialize for Uuid { + fn serialize(&self, writer: &mut W) -> Result<()> { + BorshSerialize::serialize(&self.as_bytes(), writer) + } +} + +impl BorshDeserialize for Uuid { + fn deserialize_reader(reader: &mut R) -> Result { + Ok(Self::from_bytes(BorshDeserialize::deserialize_reader( + reader, + )?)) + } +} + +#[cfg(test)] +mod borsh_tests { + use super::*; + + #[test] + fn test_serialize() { + let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4"; + let uuid = Uuid::parse_str(uuid_str).unwrap(); + let uuid_bytes = uuid.as_bytes().to_vec(); + let borsh_bytes = uuid.try_to_vec().unwrap(); + assert_eq!(uuid_bytes, borsh_bytes); + } + + #[test] + fn test_deserialize() { + use std::string::ToString; + let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4"; + let uuid = Uuid::parse_str(uuid_str).unwrap(); + let uuid_bytes = uuid.as_bytes().to_vec(); + let deserialized = Uuid::try_from_slice(&uuid_bytes).unwrap().to_string(); + assert_eq!(uuid_str, deserialized); + } +} diff --git a/src/lib.rs b/src/lib.rs index c4695040..fe51d7dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -105,6 +105,8 @@ //! `serde`. //! * `arbitrary` - adds an `Arbitrary` trait implementation to `Uuid` for //! fuzzing. +//! * `borsh` - adds the ability to serialize and deserialize a UUID using +//! `borsh`. //! * `fast-rng` - uses a faster algorithm for generating random UUIDs. //! This feature requires more dependencies to compile, but is just as suitable for //! UUIDs as the default algorithm.