uguid/
lib.rs

1// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Library providing a GUID (Globally Unique Identifier) type. The
10//! format is defined in [RFC 4122]. However, unlike "normal" UUIDs
11//! (such as those provided by the [`uuid`] crate), the first three
12//! fields are little-endian. See [Appendix A] of the UEFI
13//! Specification. This format of GUID is also used in Microsoft
14//! Windows.
15//!
16//! [Appendix A]: https://uefi.org/specs/UEFI/2.10/Apx_A_GUID_and_Time_Formats.html
17//! [RFC 4122]: https://datatracker.ietf.org/doc/html/rfc4122
18//! [`uuid`]: https://docs.rs/uuid/latest/uuid
19//!
20//! # Features
21//!
22//! No features are enabled by default.
23//!
24//! * `bytemuck`: Implements bytemuck's `Pod` and `Zeroable` traits for `Guid`.
25//! * `serde`: Implements serde's `Serialize` and `Deserialize` traits for `Guid`.
26//! * `std`: Provides `std::error::Error` implementation for the error type.
27//!
28//! # Examples
29//!
30//! Construct a GUID at compile time with the `guid!` macro:
31//!
32//! ```
33//! use uguid::guid;
34//!
35//! let guid = guid!("01234567-89ab-cdef-0123-456789abcdef");
36//! ```
37//!
38//! Parse a GUID at runtime from a string:
39//!
40//! ```
41//! use uguid::Guid;
42//!
43//! let guid: Guid = "01234567-89ab-cdef-0123-456789abcdef".parse().unwrap();
44//! ```
45//!
46//! Construct a GUID from its components or a byte array:
47//!
48//! ```
49//! use uguid::Guid;
50//!
51//! ##[rustfmt::skip]
52//! let guid1 = Guid::from_bytes([
53//!     0x01, 0x02, 0x03, 0x04,
54//!     0x05, 0x06, 0x07, 0x08,
55//!     0x09, 0x10, 0x11, 0x12,
56//!     0x13, 0x14, 0x15, 0x16,
57//! ]);
58//! let guid2 = Guid::new(
59//!     [0x01, 0x02, 0x03, 0x04],
60//!     [0x05, 0x06],
61//!     [0x07, 0x08],
62//!     0x09,
63//!     0x10,
64//!     [0x11, 0x12, 0x13, 0x14, 0x15, 0x16],
65//! );
66//! assert_eq!(guid1, guid2);
67//! ```
68//!
69//! Convert to a string or a byte array:
70//!
71//! ```
72//! use uguid::guid;
73//!
74//! let guid = guid!("01234567-89ab-cdef-0123-456789abcdef");
75//! assert_eq!(guid.to_string(), "01234567-89ab-cdef-0123-456789abcdef");
76//! assert_eq!(
77//!     guid.to_bytes(),
78//!     [
79//!         0x67, 0x45, 0x23, 0x01, 0xab, 0x89, 0xef, 0xcd, 0x01, 0x23, 0x45,
80//!         0x67, 0x89, 0xab, 0xcd, 0xef
81//!     ]
82//! );
83//! ```
84
85#![cfg_attr(not(feature = "std"), no_std)]
86#![cfg_attr(docsrs, feature(doc_auto_cfg))]
87#![warn(missing_copy_implementations)]
88#![warn(missing_debug_implementations)]
89#![warn(missing_docs)]
90#![warn(trivial_casts)]
91#![warn(trivial_numeric_casts)]
92#![warn(unreachable_pub)]
93#![warn(unsafe_code)]
94#![warn(clippy::pedantic)]
95#![warn(clippy::as_conversions)]
96#![allow(clippy::missing_errors_doc)]
97#![allow(clippy::module_name_repetitions)]
98
99/// Macro replacement for the `?` operator, which cannot be used in
100/// const functions.
101macro_rules! mtry {
102    ($expr:expr $(,)?) => {
103        match $expr {
104            Ok(val) => val,
105            Err(err) => {
106                return Err(err);
107            }
108        }
109    };
110}
111
112mod error;
113mod guid;
114mod util;
115
116pub use error::GuidFromStrError;
117pub use guid::{Guid, Variant};
118
119#[cfg(feature = "std")]
120impl std::error::Error for GuidFromStrError {}
121
122/// Create a [`Guid`] from a string at compile time.
123///
124/// # Examples
125///
126/// ```
127/// use uguid::{guid, Guid};
128/// assert_eq!(
129///     guid!("01234567-89ab-cdef-0123-456789abcdef"),
130///     Guid::new(
131///         [0x67, 0x45, 0x23, 0x01],
132///         [0xab, 0x89],
133///         [0xef, 0xcd],
134///         0x01,
135///         0x23,
136///         [0x45, 0x67, 0x89, 0xab, 0xcd, 0xef],
137///     )
138/// );
139/// ```
140#[macro_export]
141macro_rules! guid {
142    ($s:literal) => {{
143        // Create a temporary const value to force an error in the input
144        // to fail at compile time.
145        const G: $crate::Guid = $crate::Guid::parse_or_panic($s);
146        G
147    }};
148}