Skip to content

Commit d7e05d4

Browse files
restructure, maintain oid structure
1 parent 950965c commit d7e05d4

File tree

5 files changed

+142
-86
lines changed

5 files changed

+142
-86
lines changed

src/error.rs

Lines changed: 11 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
mod datetime;
2+
mod oid;
23
mod uuid;
4+
mod value_access;
35

46
use thiserror::Error;
57

6-
use crate::spec::ElementType;
7-
88
pub use datetime::DateTimeErrorKind;
9+
pub use oid::ObjectIdErrorKind;
910
pub use uuid::UuidErrorKind;
11+
pub use value_access::ValueAccessErrorKind;
1012

1113
pub type Result<T> = std::result::Result<T, Error>;
1214

@@ -63,6 +65,13 @@ pub enum ErrorKind {
6365
message: String,
6466
},
6567

68+
/// An error related to the [`ObjectId`](crate::oid::ObjectId) type occurred.
69+
#[error("An ObjectId-related error occurred: {kind}")]
70+
ObjectId {
71+
/// The kind of error that occurred.
72+
kind: ObjectIdErrorKind,
73+
},
74+
6675
/// Invalid UTF-8 bytes were encountered.
6776
#[error("Invalid UTF-8")]
6877
Utf8Encoding,
@@ -108,31 +117,6 @@ impl From<crate::de::Error> for Error {
108117
}
109118
}
110119

111-
/// The types of errors that can occur when attempting to access a value in a document.
112-
#[derive(Clone, Debug, Error)]
113-
#[non_exhaustive]
114-
pub enum ValueAccessErrorKind {
115-
/// No value for the specified key was present in the document.
116-
#[error("The key was not present in the document")]
117-
NotPresent,
118-
119-
/// The type of the value in the document did not match the requested type.
120-
#[error("Expected type {expected:?}, got type {actual:?}")]
121-
#[non_exhaustive]
122-
UnexpectedType {
123-
/// The actual type of the value.
124-
actual: ElementType,
125-
126-
/// The expected type of the value.
127-
expected: ElementType,
128-
},
129-
130-
/// An error occurred when attempting to parse the document's BSON bytes.
131-
#[error("{message}")]
132-
#[non_exhaustive]
133-
InvalidBson { message: String },
134-
}
135-
136120
impl Error {
137121
pub(crate) fn with_key(mut self, key: impl Into<String>) -> Self {
138122
self.key = Some(key.into());
@@ -144,27 +128,6 @@ impl Error {
144128
self
145129
}
146130

147-
pub(crate) fn value_access_not_present() -> Self {
148-
ErrorKind::ValueAccess {
149-
kind: ValueAccessErrorKind::NotPresent,
150-
}
151-
.into()
152-
}
153-
154-
pub(crate) fn value_access_unexpected_type(actual: ElementType, expected: ElementType) -> Self {
155-
ErrorKind::ValueAccess {
156-
kind: ValueAccessErrorKind::UnexpectedType { actual, expected },
157-
}
158-
.into()
159-
}
160-
161-
pub(crate) fn value_access_invalid_bson(message: String) -> Self {
162-
ErrorKind::ValueAccess {
163-
kind: ValueAccessErrorKind::InvalidBson { message },
164-
}
165-
.into()
166-
}
167-
168131
pub(crate) fn malformed_bytes(message: impl ToString) -> Self {
169132
ErrorKind::MalformedBytes {
170133
message: message.to_string(),
@@ -178,26 +141,4 @@ impl Error {
178141
}
179142
.into()
180143
}
181-
182-
#[cfg(test)]
183-
pub(crate) fn is_value_access_not_present(&self) -> bool {
184-
matches!(
185-
self.kind,
186-
ErrorKind::ValueAccess {
187-
kind: ValueAccessErrorKind::NotPresent,
188-
..
189-
}
190-
)
191-
}
192-
193-
#[cfg(test)]
194-
pub(crate) fn is_value_access_unexpected_type(&self) -> bool {
195-
matches!(
196-
self.kind,
197-
ErrorKind::ValueAccess {
198-
kind: ValueAccessErrorKind::UnexpectedType { .. },
199-
..
200-
}
201-
)
202-
}
203144
}

src/error/datetime.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use thiserror::Error as ThisError;
22

33
use crate::error::{Error, ErrorKind};
44

5+
/// The kinds of errors that can occur when working with the [`DateTime`](crate::DateTime) type.
56
#[derive(Clone, Debug, ThisError)]
67
pub enum DateTimeErrorKind {
78
/// The `DateTime` could not be formatted.

src/error/oid.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use hex::FromHexError;
2+
use thiserror::Error as ThisError;
3+
4+
use crate::error::{Error, ErrorKind};
5+
6+
/// The kinds of errors that can occur when working with the [`ObjectId`](crate::oid::ObjectId)
7+
/// type.
8+
#[derive(Clone, Debug, ThisError)]
9+
pub enum ObjectIdErrorKind {
10+
/// An invalid character was found in the provided hex string. Valid characters are: `0...9`,
11+
/// `a...f`, or `A...F`.
12+
#[error("invalid character '{c}' encountered at index {index}")]
13+
#[non_exhaustive]
14+
InvalidHexStringCharacter {
15+
/// The invalid character.
16+
c: char,
17+
18+
/// The index at which the invalid character was encountered.
19+
index: usize,
20+
},
21+
22+
/// An `ObjectId` with an invalid length was encountered.
23+
#[error("invalid hex string length {length}")]
24+
#[non_exhaustive]
25+
InvalidHexStringLength {
26+
/// The length of the invalid hex string.
27+
length: usize,
28+
},
29+
}
30+
31+
impl Error {
32+
// This method is not a From implementation so that it is not part of the public API.
33+
pub(crate) fn from_hex_error(error: FromHexError, length: usize) -> Self {
34+
let kind = match error {
35+
FromHexError::InvalidHexCharacter { c, index } => {
36+
ObjectIdErrorKind::InvalidHexStringCharacter { c, index }
37+
}
38+
FromHexError::InvalidStringLength | FromHexError::OddLength => {
39+
ObjectIdErrorKind::InvalidHexStringLength { length }
40+
}
41+
};
42+
ErrorKind::ObjectId { kind }.into()
43+
}
44+
45+
pub(crate) fn oid_invalid_length(length: usize) -> Self {
46+
ErrorKind::ObjectId {
47+
kind: ObjectIdErrorKind::InvalidHexStringLength { length },
48+
}
49+
.into()
50+
}
51+
}

src/error/value_access.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use thiserror::Error as ThisError;
2+
3+
use crate::{
4+
error::{Error, ErrorKind},
5+
spec::ElementType,
6+
};
7+
8+
/// The types of errors that can occur when attempting to access a value in a document.
9+
#[derive(Clone, Debug, ThisError)]
10+
#[non_exhaustive]
11+
pub enum ValueAccessErrorKind {
12+
/// No value for the specified key was present in the document.
13+
#[error("the key was not present in the document")]
14+
NotPresent,
15+
16+
/// The type of the value in the document did not match the requested type.
17+
#[error("expected type {expected:?}, got type {actual:?}")]
18+
#[non_exhaustive]
19+
UnexpectedType {
20+
/// The actual type of the value.
21+
actual: ElementType,
22+
23+
/// The expected type of the value.
24+
expected: ElementType,
25+
},
26+
27+
/// An error occurred when attempting to parse the document's BSON bytes.
28+
#[error("{message}")]
29+
#[non_exhaustive]
30+
InvalidBson { message: String },
31+
}
32+
33+
impl Error {
34+
pub(crate) fn value_access_not_present() -> Self {
35+
ErrorKind::ValueAccess {
36+
kind: ValueAccessErrorKind::NotPresent,
37+
}
38+
.into()
39+
}
40+
41+
pub(crate) fn value_access_unexpected_type(actual: ElementType, expected: ElementType) -> Self {
42+
ErrorKind::ValueAccess {
43+
kind: ValueAccessErrorKind::UnexpectedType { actual, expected },
44+
}
45+
.into()
46+
}
47+
48+
pub(crate) fn value_access_invalid_bson(message: String) -> Self {
49+
ErrorKind::ValueAccess {
50+
kind: ValueAccessErrorKind::InvalidBson { message },
51+
}
52+
.into()
53+
}
54+
55+
#[cfg(test)]
56+
pub(crate) fn is_value_access_not_present(&self) -> bool {
57+
matches!(
58+
self.kind,
59+
ErrorKind::ValueAccess {
60+
kind: ValueAccessErrorKind::NotPresent,
61+
..
62+
}
63+
)
64+
}
65+
66+
#[cfg(test)]
67+
pub(crate) fn is_value_access_unexpected_type(&self) -> bool {
68+
matches!(
69+
self.kind,
70+
ErrorKind::ValueAccess {
71+
kind: ValueAccessErrorKind::UnexpectedType { .. },
72+
..
73+
}
74+
)
75+
}
76+
}

src/oid.rs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use std::{
99
sync::atomic::{AtomicUsize, Ordering},
1010
};
1111

12-
use hex::{self, FromHexError};
1312
use once_cell::sync::Lazy;
1413
use rand::{random, rng, Rng};
1514

@@ -154,22 +153,10 @@ impl ObjectId {
154153
pub fn parse_str(s: impl AsRef<str>) -> Result<ObjectId> {
155154
let s = s.as_ref();
156155

157-
let bytes: Vec<u8> = hex::decode(s.as_bytes()).map_err(|e| {
158-
let message = match e {
159-
FromHexError::InvalidHexCharacter { c, index } => {
160-
format!("invalid hex character {c} encountered at index {index}")
161-
}
162-
FromHexError::InvalidStringLength | FromHexError::OddLength => {
163-
format!("invalid hex string length {}", s.len())
164-
}
165-
};
166-
Error::invalid_value(message)
167-
})?;
156+
let bytes: Vec<u8> =
157+
hex::decode(s.as_bytes()).map_err(|e| Error::from_hex_error(e, s.len()))?;
168158
if bytes.len() != 12 {
169-
Err(Error::invalid_value(format!(
170-
"invalid object ID byte vector length {}",
171-
bytes.len()
172-
)))
159+
Err(Error::oid_invalid_length(bytes.len()))
173160
} else {
174161
let mut byte_array: [u8; 12] = [0; 12];
175162
byte_array[..].copy_from_slice(&bytes[..]);

0 commit comments

Comments
 (0)