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.
101 macro_rules! mtry {
102     ($expr:expr $(,)?) => {
103         match $expr {
104             Ok(val) => val,
105             Err(err) => {
106                 return Err(err);
107             }
108         }
109     };
110 }
111 
112 mod error;
113 mod guid;
114 mod util;
115 
116 pub use error::GuidFromStrError;
117 pub use guid::{Guid, Variant};
118 
119 #[cfg(feature = "std")]
120 impl 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]
141 macro_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 }
149