Skip to content

Commit ea5424a

Browse files
maintain uuid structure
1 parent 902a8d0 commit ea5424a

File tree

3 files changed

+109
-80
lines changed

3 files changed

+109
-80
lines changed

src/error.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
mod uuid;
2+
13
use thiserror::Error;
24

35
use crate::spec::ElementType;
46

7+
pub use uuid::UuidErrorKind;
8+
59
pub type Result<T> = std::result::Result<T, Error>;
610

711
/// An error that can occur in the `bson` crate.
@@ -52,6 +56,13 @@ pub enum ErrorKind {
5256
#[error("Invalid UTF-8")]
5357
Utf8Encoding,
5458

59+
/// An error related to the [`Uuid`](crate::uuid::Uuid) type occurred.
60+
#[error("A UUID-related error occurred: {kind}")]
61+
Uuid {
62+
/// The kind of error that occurred.
63+
kind: UuidErrorKind,
64+
},
65+
5566
/// An error occurred when attempting to access a value in a document.
5667
#[error("An error occurred when attempting to access a document value: {kind}")]
5768
#[non_exhaustive]

src/error/uuid.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use thiserror::Error as ThisError;
2+
3+
use crate::{
4+
error::{Error, ErrorKind},
5+
spec::BinarySubtype,
6+
UuidRepresentation,
7+
};
8+
9+
/// The kinds of errors that can occur when working with the [`Uuid`](crate::uuid::Uuid) type.
10+
#[derive(Clone, Debug, ThisError)]
11+
#[non_exhaustive]
12+
pub enum UuidErrorKind {
13+
/// An invalid string was used to construct a UUID.
14+
#[error("Invalid UUID string: {message}")]
15+
#[non_exhaustive]
16+
InvalidString {
17+
/// A message describing the error.
18+
message: String,
19+
},
20+
21+
/// The requested [`UuidRepresentation`] does not match the binary subtype of a [`Binary`]
22+
/// value.
23+
#[error(
24+
"UUID representation mismatch: expected binary subtype {expected_binary_subtype:?} for \
25+
representation {requested_representation:?}, got {actual_binary_subtype:?}"
26+
)]
27+
#[non_exhaustive]
28+
RepresentationMismatch {
29+
/// The subtype that was expected given the requested representation.
30+
expected_binary_subtype: BinarySubtype,
31+
32+
/// The actual subtype of the binary value.
33+
actual_binary_subtype: BinarySubtype,
34+
35+
/// The requested representation.
36+
requested_representation: UuidRepresentation,
37+
},
38+
39+
/// An invalid length of bytes was used to construct a UUID value.
40+
#[error("Invalid UUID length: expected 16 bytes, got {length}")]
41+
#[non_exhaustive]
42+
InvalidLength {
43+
/// The actual length of the data.
44+
length: usize,
45+
},
46+
}
47+
48+
impl Error {
49+
pub(crate) fn invalid_uuid_string(message: impl ToString) -> Self {
50+
ErrorKind::Uuid {
51+
kind: UuidErrorKind::InvalidString {
52+
message: message.to_string(),
53+
},
54+
}
55+
.into()
56+
}
57+
58+
pub(crate) fn uuid_representation_mismatch(
59+
requested_representation: UuidRepresentation,
60+
actual_binary_subtype: BinarySubtype,
61+
expected_binary_subtype: BinarySubtype,
62+
) -> Self {
63+
ErrorKind::Uuid {
64+
kind: UuidErrorKind::RepresentationMismatch {
65+
expected_binary_subtype,
66+
actual_binary_subtype,
67+
requested_representation,
68+
},
69+
}
70+
.into()
71+
}
72+
73+
pub(crate) fn invalid_uuid_length(length: usize) -> Self {
74+
ErrorKind::Uuid {
75+
kind: UuidErrorKind::InvalidLength { length },
76+
}
77+
.into()
78+
}
79+
}

src/uuid.rs

Lines changed: 19 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,13 @@ use std::{
142142

143143
use serde::{Deserialize, Serialize};
144144

145-
use crate::{de::BsonVisitor, spec::BinarySubtype, Binary, Bson};
145+
use crate::{
146+
de::BsonVisitor,
147+
error::{Error, Result},
148+
spec::BinarySubtype,
149+
Binary,
150+
Bson,
151+
};
146152

147153
/// Special type name used in the [`Uuid`] serialization implementation to indicate a BSON
148154
/// UUID is being serialized or deserialized. The BSON serializers/deserializers will handle this
@@ -189,9 +195,7 @@ impl Uuid {
189195

190196
/// Creates a [`Uuid`] from the provided hex string.
191197
pub fn parse_str(input: impl AsRef<str>) -> Result<Self> {
192-
let uuid = uuid::Uuid::parse_str(input.as_ref()).map_err(|e| Error::InvalidUuidString {
193-
message: e.to_string(),
194-
})?;
198+
let uuid = uuid::Uuid::parse_str(input.as_ref()).map_err(Error::invalid_uuid_string)?;
195199
Ok(Self::from_external_uuid(uuid))
196200
}
197201

@@ -394,25 +398,23 @@ impl Binary {
394398
pub fn to_uuid_with_representation(&self, rep: UuidRepresentation) -> Result<Uuid> {
395399
// If representation is non-standard, then its subtype must be UuidOld
396400
if rep != UuidRepresentation::Standard && self.subtype != BinarySubtype::UuidOld {
397-
return Err(Error::RepresentationMismatch {
398-
requested_representation: rep,
399-
actual_binary_subtype: self.subtype,
400-
expected_binary_subtype: BinarySubtype::UuidOld,
401-
});
401+
return Err(Error::uuid_representation_mismatch(
402+
rep,
403+
self.subtype,
404+
BinarySubtype::UuidOld,
405+
));
402406
}
403407
// If representation is standard, then its subtype must be Uuid
404408
if rep == UuidRepresentation::Standard && self.subtype != BinarySubtype::Uuid {
405-
return Err(Error::RepresentationMismatch {
406-
requested_representation: rep,
407-
actual_binary_subtype: self.subtype,
408-
expected_binary_subtype: BinarySubtype::Uuid,
409-
});
409+
return Err(Error::uuid_representation_mismatch(
410+
rep,
411+
self.subtype,
412+
BinarySubtype::UuidOld,
413+
));
410414
}
411415
// Must be 16 bytes long
412416
if self.bytes.len() != 16 {
413-
return Err(Error::InvalidLength {
414-
length: self.bytes.len(),
415-
});
417+
return Err(Error::invalid_uuid_length(self.bytes.len()));
416418
}
417419
let mut buf = [0u8; 16];
418420
buf.copy_from_slice(&self.bytes);
@@ -479,66 +481,3 @@ macro_rules! trait_impls {
479481
};
480482
}
481483
trait_impls!(feature = "uuid-1", uuid::Uuid);
482-
483-
/// Errors that can occur during [`Uuid`] construction and generation.
484-
#[derive(Clone, Debug)]
485-
#[non_exhaustive]
486-
pub enum Error {
487-
/// Error returned when an invalid string is provided to [`Uuid::parse_str`].
488-
#[non_exhaustive]
489-
InvalidUuidString { message: String },
490-
491-
/// Error returned when the representation specified does not match the underlying
492-
/// [`crate::Binary`] value in [`crate::Binary::to_uuid_with_representation`].
493-
#[non_exhaustive]
494-
RepresentationMismatch {
495-
/// The subtype that was expected given the requested representation.
496-
expected_binary_subtype: BinarySubtype,
497-
498-
/// The actual subtype of the binary value.
499-
actual_binary_subtype: BinarySubtype,
500-
501-
/// The requested representation.
502-
requested_representation: UuidRepresentation,
503-
},
504-
505-
/// Error returned from [`crate::Binary::to_uuid`] if the underling data is not 16 bytes long.
506-
#[non_exhaustive]
507-
InvalidLength {
508-
/// The actual length of the data.
509-
length: usize,
510-
},
511-
}
512-
513-
/// Alias for `Result<T, bson::uuid::Error>`.
514-
pub type Result<T> = std::result::Result<T, Error>;
515-
516-
impl fmt::Display for Error {
517-
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
518-
match self {
519-
Error::InvalidUuidString { message } => {
520-
write!(fmt, "{}", message)
521-
}
522-
Error::RepresentationMismatch {
523-
expected_binary_subtype,
524-
actual_binary_subtype,
525-
requested_representation,
526-
} => {
527-
write!(
528-
fmt,
529-
"expected {:?} when converting to UUID with {:?}, isntead got {:?}",
530-
expected_binary_subtype, requested_representation, actual_binary_subtype
531-
)
532-
}
533-
Error::InvalidLength { length } => {
534-
write!(
535-
fmt,
536-
"expected UUID to contain 16 bytes, instead got {}",
537-
length
538-
)
539-
}
540-
}
541-
}
542-
}
543-
544-
impl std::error::Error for Error {}

0 commit comments

Comments
 (0)