Skip to content

Commit

Permalink
Add new_random and new_from_uuid
Browse files Browse the repository at this point in the history
  • Loading branch information
sunsided committed Apr 8, 2023
1 parent 57b7052 commit 02f9b45
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 12 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
All notable changes to this project will be documented in this file.
This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

### Added

- Added `new_random` when using the `random` crate feature.
- Added `new_from_uuid` to create a `ShortGuid` from an existing UUID.

## 0.2.0 - 2023-04-08

### Added
Expand Down
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,10 @@ base64 = "0.21.0"
uuid = "1.3.0"

[features]
default = ["random"]
arbitrary = ["uuid/arbitrary", "arbitrary/derive"]
random = ["uuid/v4"]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
26 changes: 19 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
# ShortGuid

Short URL-safe Base64 encoded UUIDs.
Short URL-safe Base64 encoded UUIDs.

---

ShortGuids transparently represent UUID types but use only 22 characters
in their string representation, as opposed to 36 characters for a dashed
UUID or 32 without dashes.

```rust
#[test]
fn it_works() {
let uuid = Uuid::try_parse("c9a646d3-9c61-4cb7-bfcd-ee2522c8f633").unwrap();
let short_guid_1 = ShortGuid::from(uuid);
let short_guid_2 = ShortGuid::try_parse("c9a646d3-9c61-4cb7-bfcd-ee2522c8f633").unwrap();
let short_guid_3 = ShortGuid::try_parse("yaZG05xhTLe_ze4lIsj2Mw").unwrap();
let from_uuid = ShortGuid::from(uuid);
let parsed_uuid = ShortGuid::try_parse("c9a646d3-9c61-4cb7-bfcd-ee2522c8f633").unwrap();
let parsed_short = ShortGuid::try_parse("yaZG05xhTLe_ze4lIsj2Mw").unwrap();

assert_eq!(from_uuid, uuid);
assert_eq!(from_uuid, "yaZG05xhTLe_ze4lIsj2Mw");
assert_eq!(from_uuid, "c9a646d3-9c61-4cb7-bfcd-ee2522c8f633");
assert_eq!(from_uuid, parsed_uuid);
assert_eq!(from_uuid, parsed_short);

assert_eq!(short_guid_1, "yaZG05xhTLe_ze4lIsj2Mw");
assert_eq!(short_guid_2, short_guid_1);
assert_eq!(short_guid_3, uuid);
let random = ShortGuid::new_random();
assert_ne!(from_uuid, random);
}
```

Expand Down
26 changes: 25 additions & 1 deletion fuzz/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 39 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@
//!
//! ```
//! # use shortguid::ShortGuid;
//! let short_guid_a = ShortGuid::try_parse("c9a646d3-9c61-4cb7-bfcd-ee2522c8f633").unwrap();
//! let short_guid_b = ShortGuid::try_parse("yaZG05xhTLe_ze4lIsj2Mw").unwrap();
//! assert_eq!(short_guid_a, "yaZG05xhTLe_ze4lIsj2Mw");
//! assert_eq!(short_guid_a, short_guid_b);
//! let from_uuid = ShortGuid::try_parse("c9a646d3-9c61-4cb7-bfcd-ee2522c8f633").unwrap();
//! let from_short = ShortGuid::try_parse("yaZG05xhTLe_ze4lIsj2Mw").unwrap();
//! assert_eq!(from_uuid, "yaZG05xhTLe_ze4lIsj2Mw");
//! assert_eq!(from_uuid, from_short);
//!
//! let random = ShortGuid::new_random();
//! assert_ne!(from_uuid, random);
//! ```
// only enables the `doc_cfg` feature when
// the `docsrs` configuration attribute is defined
#![cfg_attr(docsrs, feature(doc_cfg))]

use base64::{DecodeError, Engine};
use std::borrow::Borrow;
use std::error::Error;
Expand Down Expand Up @@ -45,6 +52,20 @@ pub struct ShortGuid(Uuid);

/// A short UUID format.
impl ShortGuid {
/// Generates a new [`ShortGuid`] based on a random UUID v4.
#[cfg_attr(docsrs, doc(cfg(feature = "random")))]
#[cfg(feature = "random")]
#[inline(always)]
pub fn new_random() -> Self {
Self::new_from_uuid(Uuid::new_v4())
}

/// Creates a new [`ShortGuid`] based on the provided [`Uuid`].
#[inline(always)]
pub const fn new_from_uuid(uuid: Uuid) -> Self {
Self(uuid)
}

/// Tries to parse the value as a [`ShortGuid`] or [`Uuid`] string, and outputs an actual
/// [`ShortGuid`] instance.
pub fn try_parse<S: AsRef<str>>(value: S) -> Result<Self, ParseError> {
Expand All @@ -56,6 +77,12 @@ impl ShortGuid {
Ok(Self(uuid))
}

/// Constructs a [`ShortGuid`] instance based on a byte slice.
///
/// ## Notes
/// This will clone the underlying data. If you wish to return a
/// transparent reference around the provided slice, use [`ShortGuid::from_bytes_ref`]
/// instead.
#[inline]
pub fn from_bytes(bytes: &[u8; 16]) -> Self {
Self(Uuid::from_bytes_ref(bytes).clone())
Expand Down Expand Up @@ -394,6 +421,14 @@ mod tests {
assert!(ShortGuid::default().is_empty());
}

#[test]
fn new_random_works() {
let a = ShortGuid::new_random();
let b = ShortGuid::new_random();
assert_ne!(a, b);
assert_ne!(a, ShortGuid::default());
}

#[test]
fn try_parse_works() {
assert_eq!(
Expand Down

0 comments on commit 02f9b45

Please sign in to comment.