Skip to content

Commit d60c7c4

Browse files
RUST-302 Implement v2 spec test runner (#208)
1 parent 5970f98 commit d60c7c4

32 files changed

+674
-343
lines changed

src/client/auth/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod test;
88
use std::{borrow::Cow, str::FromStr};
99

1010
use rand::Rng;
11+
use serde::Deserialize;
1112
use typed_builder::TypedBuilder;
1213

1314
use self::scram::ScramVersion;
@@ -27,7 +28,7 @@ const PLAIN_STR: &str = "PLAIN";
2728
/// The authentication mechanisms supported by MongoDB.
2829
///
2930
/// Note: not all of these mechanisms are currently supported by the driver.
30-
#[derive(Clone, PartialEq, Debug)]
31+
#[derive(Clone, Deserialize, PartialEq, Debug)]
3132
pub enum AuthMechanism {
3233
/// MongoDB Challenge Response nonce and MD5 based authentication system. It is currently
3334
/// deprecated and will never be supported by this driver.
@@ -177,7 +178,7 @@ impl FromStr for AuthMechanism {
177178
///
178179
/// Some fields (mechanism and source) may be omitted and will either be negotiated or assigned a
179180
/// default value, depending on the values of other fields in the credential.
180-
#[derive(Clone, Debug, Default, TypedBuilder, PartialEq)]
181+
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, PartialEq)]
181182
pub struct Credential {
182183
/// The username to authenticate with. This applies to all mechanisms but may be omitted when
183184
/// authenticating via MONGODB-X509.

src/client/options/mod.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustls::{
2222
ServerCertVerifier,
2323
TLSError,
2424
};
25+
use serde::Deserialize;
2526
use strsim::jaro_winkler;
2627
use typed_builder::TypedBuilder;
2728
use webpki_roots::TLS_SERVER_ROOTS;
@@ -89,7 +90,7 @@ lazy_static! {
8990
}
9091

9192
/// A hostname:port address pair.
92-
#[derive(Clone, Debug, Eq)]
93+
#[derive(Clone, Debug, Deserialize, Eq)]
9394
pub struct StreamAddress {
9495
/// The hostname of the address.
9596
pub hostname: String,
@@ -191,8 +192,9 @@ impl fmt::Display for StreamAddress {
191192
}
192193

193194
/// Contains the options that can be used to create a new [`Client`](../struct.Client.html).
194-
#[derive(Clone, Derivative, TypedBuilder)]
195+
#[derive(Clone, Derivative, Deserialize, TypedBuilder)]
195196
#[derivative(Debug, PartialEq)]
197+
#[serde(rename_all = "camelCase")]
196198
#[non_exhaustive]
197199
pub struct ClientOptions {
198200
/// The initial list of seeds that the Client should connect to.
@@ -204,6 +206,7 @@ pub struct ClientOptions {
204206
hostname: \"localhost\".to_string(),
205207
port: Some(27017),
206208
}]")]
209+
#[serde(default = "default_hosts")]
207210
pub hosts: Vec<StreamAddress>,
208211

209212
/// The application name that the Client will send to the server as part of the handshake. This
@@ -219,12 +222,14 @@ pub struct ClientOptions {
219222
/// CmapEventHandler type documentation for more details.
220223
#[derivative(Debug = "ignore", PartialEq = "ignore")]
221224
#[builder(default)]
225+
#[serde(skip)]
222226
pub cmap_event_handler: Option<Arc<dyn CmapEventHandler>>,
223227

224228
/// The handler that should process all command-related events. See the CommandEventHandler
225229
/// type documentation for more details.
226230
#[derivative(Debug = "ignore", PartialEq = "ignore")]
227231
#[builder(default)]
232+
#[serde(skip)]
228233
pub command_event_handler: Option<Arc<dyn CommandEventHandler>>,
229234

230235
/// The connect timeout passed to each underlying TcpStream when attemtping to connect to the
@@ -351,10 +356,17 @@ pub struct ClientOptions {
351356
pub(crate) zlib_compression: Option<i32>,
352357

353358
#[builder(default)]
354-
original_srv_hostname: Option<String>,
359+
pub(crate) original_srv_hostname: Option<String>,
355360

356361
#[builder(default)]
357-
original_uri: Option<String>,
362+
pub(crate) original_uri: Option<String>,
363+
}
364+
365+
fn default_hosts() -> Vec<StreamAddress> {
366+
vec![StreamAddress {
367+
hostname: "localhost".to_string(),
368+
port: Some(27017),
369+
}]
358370
}
359371

360372
impl Default for ClientOptions {
@@ -400,7 +412,7 @@ struct ClientOptionsParser {
400412

401413
/// Specifies whether TLS configuration should be used with the operations that the
402414
/// [`Client`](../struct.Client.html) performs.
403-
#[derive(Clone, Debug, PartialEq)]
415+
#[derive(Clone, Debug, Deserialize, PartialEq)]
404416
pub enum Tls {
405417
Enabled(TlsOptions),
406418
Disabled,
@@ -419,7 +431,7 @@ impl From<TlsOptions> for Option<Tls> {
419431
}
420432

421433
/// Specifies the TLS configuration that the [`Client`](../struct.Client.html) should use.
422-
#[derive(Clone, Debug, Default, PartialEq, TypedBuilder)]
434+
#[derive(Clone, Debug, Default, Deserialize, PartialEq, TypedBuilder)]
423435
#[non_exhaustive]
424436
pub struct TlsOptions {
425437
/// Whether or not the [`Client`](../struct.Client.html) should return an error if the server
@@ -517,7 +529,7 @@ impl TlsOptions {
517529

518530
/// Extra information to append to the driver version in the metadata of the handshake with the
519531
/// server. This should be used by libraries wrapping the driver, e.g. ODMs.
520-
#[derive(Clone, Debug, TypedBuilder, PartialEq)]
532+
#[derive(Clone, Debug, Deserialize, TypedBuilder, PartialEq)]
521533
#[non_exhaustive]
522534
pub struct DriverInfo {
523535
/// The name of the library wrapping the driver.

src/coll/options.rs

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,21 @@ use typed_builder::TypedBuilder;
66

77
use crate::{
88
bson::{doc, Bson, Document},
9-
bson_util::{serialize_batch_size, serialize_duration_as_int_millis, serialize_u32_as_i32},
9+
bson_util::{
10+
deserialize_duration_from_u64_millis,
11+
serialize_batch_size,
12+
serialize_duration_as_int_millis,
13+
serialize_u32_as_i32,
14+
},
1015
concern::{ReadConcern, WriteConcern},
1116
options::Collation,
1217
selection_criteria::SelectionCriteria,
1318
};
1419

1520
/// These are the valid options for creating a [`Collection`](../struct.Collection.html) with
1621
/// [`Database::collection_with_options`](../struct.Database.html#method.collection_with_options).
17-
#[derive(Debug, Default, TypedBuilder)]
22+
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
23+
#[serde(rename_all = "camelCase")]
1824
#[non_exhaustive]
1925
pub struct CollectionOptions {
2026
/// The default read preference for operations.
@@ -34,7 +40,7 @@ pub struct CollectionOptions {
3440
/// [`Collection::find_one_and_replace`](../struct.Collection.html#method.find_one_and_replace) and
3541
/// [`Collection::find_one_and_update`](../struct.Collection.html#method.find_one_and_update)
3642
/// operation should return the document before or after modification.
37-
#[derive(Debug)]
43+
#[derive(Clone, Debug, Deserialize)]
3844
#[non_exhaustive]
3945
pub enum ReturnDocument {
4046
/// Return the document after modification.
@@ -81,7 +87,8 @@ pub enum CursorType {
8187

8288
/// Specifies the options to a
8389
/// [`Collection::insert_one`](../struct.Collection.html#method.insert_one) operation.
84-
#[derive(Clone, Debug, Default, TypedBuilder)]
90+
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
91+
#[serde(rename_all = "camelCase")]
8592
#[non_exhaustive]
8693
pub struct InsertOneOptions {
8794
/// Opt out of document-level validation.
@@ -130,7 +137,7 @@ impl InsertManyOptions {
130137
/// Enum modeling the modifications to apply during an update.
131138
/// For details, see the official MongoDB
132139
/// [documentation](https://docs.mongodb.com/manual/reference/command/update/#update-command-behaviors)
133-
#[derive(Clone, Debug, Serialize)]
140+
#[derive(Clone, Debug, Deserialize, Serialize)]
134141
#[serde(untagged)]
135142
#[non_exhaustive]
136143
pub enum UpdateModifications {
@@ -168,7 +175,8 @@ impl From<Vec<Document>> for UpdateModifications {
168175
/// Specifies the options to a
169176
/// [`Collection::update_one`](../struct.Collection.html#method.update_one) or
170177
/// [`Collection::update_many`](../struct.Collection.html#method.update_many) operation.
171-
#[derive(Debug, Default, TypedBuilder)]
178+
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
179+
#[serde(rename_all = "camelCase")]
172180
#[non_exhaustive]
173181
pub struct UpdateOptions {
174182
/// A set of filters specifying to which array elements an update should apply.
@@ -220,7 +228,8 @@ impl UpdateOptions {
220228

221229
/// Specifies the options to a
222230
/// [`Collection::replace_one`](../struct.Collection.html#method.replace_one) operation.
223-
#[derive(Debug, Default, TypedBuilder)]
231+
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
232+
#[serde(rename_all = "camelCase")]
224233
#[non_exhaustive]
225234
pub struct ReplaceOptions {
226235
/// Opt out of document-level validation.
@@ -254,7 +263,7 @@ pub struct ReplaceOptions {
254263
/// [`Collection::delete_one`](../struct.Collection.html#method.delete_one) or
255264
/// [`Collection::delete_many`](../struct.Collection.html#method.delete_many) operation.
256265
#[serde_with::skip_serializing_none]
257-
#[derive(Clone, Debug, Default, TypedBuilder, Serialize)]
266+
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, Serialize)]
258267
#[serde(rename_all = "camelCase")]
259268
#[non_exhaustive]
260269
pub struct DeleteOptions {
@@ -366,7 +375,7 @@ pub struct FindOneAndReplaceOptions {
366375
/// Specifies the options to a
367376
/// [`Collection::find_one_and_update`](../struct.Collection.html#method.find_one_and_update)
368377
/// operation.
369-
#[derive(Debug, Default, TypedBuilder)]
378+
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
370379
#[non_exhaustive]
371380
pub struct FindOneAndUpdateOptions {
372381
/// A set of filters specifying to which array elements an update should apply.
@@ -424,7 +433,7 @@ pub struct FindOneAndUpdateOptions {
424433
/// operation.
425434
#[skip_serializing_none]
426435
#[serde(rename_all = "camelCase")]
427-
#[derive(Clone, Debug, Default, TypedBuilder, Serialize)]
436+
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, Serialize)]
428437
#[non_exhaustive]
429438
pub struct AggregateOptions {
430439
/// Enables writing to temporary files. When set to true, aggregation stages can write data to
@@ -439,7 +448,7 @@ pub struct AggregateOptions {
439448
/// number of round trips needed to return the entire set of documents returned by the
440449
/// query).
441450
#[builder(default)]
442-
#[serde(serialize_with = "serialize_batch_size", rename = "cursor")]
451+
#[serde(serialize_with = "serialize_batch_size", rename(serialize = "cursor"))]
443452
pub batch_size: Option<u32>,
444453

445454
/// Opt out of document-level validation.
@@ -467,7 +476,10 @@ pub struct AggregateOptions {
467476
///
468477
/// This option will have no effect on non-tailable cursors that result from this operation.
469478
#[builder(default)]
470-
#[serde(skip)]
479+
#[serde(
480+
skip_serializing,
481+
deserialize_with = "deserialize_duration_from_u64_millis"
482+
)]
471483
pub max_await_time: Option<Duration>,
472484

473485
/// The maximum amount of time to allow the query to run.
@@ -477,7 +489,8 @@ pub struct AggregateOptions {
477489
#[builder(default)]
478490
#[serde(
479491
serialize_with = "serialize_duration_as_int_millis",
480-
rename = "maxTimeMS"
492+
rename = "maxTimeMS",
493+
deserialize_with = "deserialize_duration_from_u64_millis"
481494
)]
482495
pub max_time: Option<Duration>,
483496

@@ -493,7 +506,8 @@ pub struct AggregateOptions {
493506
/// If none is specified, the selection criteria defined on the object executing this operation
494507
/// will be used.
495508
#[builder(default)]
496-
#[serde(skip)]
509+
#[serde(skip_serializing)]
510+
#[serde(rename = "readPreference")]
497511
pub selection_criteria: Option<SelectionCriteria>,
498512

499513
/// The write concern to use for the operation.
@@ -506,7 +520,8 @@ pub struct AggregateOptions {
506520

507521
/// Specifies the options to a
508522
/// [`Collection::count_documents`](../struct.Collection.html#method.count_documents) operation.
509-
#[derive(Debug, Default, TypedBuilder)]
523+
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
524+
#[serde(rename_all = "camelCase")]
510525
#[non_exhaustive]
511526
pub struct CountOptions {
512527
/// The index to use for the operation.
@@ -522,6 +537,7 @@ pub struct CountOptions {
522537
/// This options maps to the `maxTimeMS` MongoDB query option, so the duration will be sent
523538
/// across the wire as an integer number of milliseconds.
524539
#[builder(default)]
540+
#[serde(deserialize_with = "deserialize_duration_from_u64_millis")]
525541
pub max_time: Option<Duration>,
526542

527543
/// The number of documents to skip before counting.
@@ -544,7 +560,7 @@ pub struct CountOptions {
544560
/// `Collection::estimated_document_count`
545561
/// ](../struct.Collection.html#method.estimated_document_count) operation.
546562
#[serde_with::skip_serializing_none]
547-
#[derive(Debug, Default, TypedBuilder, Serialize, Clone)]
563+
#[derive(Debug, Default, Deserialize, TypedBuilder, Serialize, Clone)]
548564
#[serde(rename_all = "camelCase")]
549565
#[non_exhaustive]
550566
pub struct EstimatedDocumentCountOptions {
@@ -555,7 +571,8 @@ pub struct EstimatedDocumentCountOptions {
555571
#[builder(default)]
556572
#[serde(
557573
serialize_with = "serialize_duration_as_int_millis",
558-
rename = "maxTimeMS"
574+
rename = "maxTimeMS",
575+
deserialize_with = "deserialize_duration_from_u64_millis"
559576
)]
560577
pub max_time: Option<Duration>,
561578

@@ -574,7 +591,7 @@ pub struct EstimatedDocumentCountOptions {
574591
/// Specifies the options to a [`Collection::distinct`](../struct.Collection.html#method.distinct)
575592
/// operation.
576593
#[serde_with::skip_serializing_none]
577-
#[derive(Debug, Default, TypedBuilder, Serialize, Clone)]
594+
#[derive(Debug, Default, Deserialize, TypedBuilder, Serialize, Clone)]
578595
#[serde(rename_all = "camelCase")]
579596
#[non_exhaustive]
580597
pub struct DistinctOptions {
@@ -585,7 +602,8 @@ pub struct DistinctOptions {
585602
#[builder(default)]
586603
#[serde(
587604
serialize_with = "serialize_duration_as_int_millis",
588-
rename = "maxTimeMS"
605+
rename = "maxTimeMS",
606+
deserialize_with = "deserialize_duration_from_u64_millis"
589607
)]
590608
pub max_time: Option<Duration>,
591609

@@ -611,7 +629,7 @@ pub struct DistinctOptions {
611629
/// Specifies the options to a [`Collection::find`](../struct.Collection.html#method.find)
612630
/// operation.
613631
#[skip_serializing_none]
614-
#[derive(Debug, Default, TypedBuilder, Serialize)]
632+
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, Serialize)]
615633
#[serde(rename_all = "camelCase")]
616634
#[non_exhaustive]
617635
pub struct FindOptions {
@@ -778,7 +796,8 @@ where
778796

779797
/// Specifies the options to a [`Collection::find_one`](../struct.Collection.html#method.find_one)
780798
/// operation.
781-
#[derive(Debug, Default, TypedBuilder)]
799+
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
800+
#[serde(rename_all = "camelCase")]
782801
#[non_exhaustive]
783802
pub struct FindOneOptions {
784803
/// If true, partial results will be returned from a mongos rather than an error being
@@ -818,6 +837,7 @@ pub struct FindOneOptions {
818837
/// This options maps to the `maxTimeMS` MongoDB query option, so the duration will be sent
819838
/// across the wire as an integer number of milliseconds.
820839
#[builder(default)]
840+
#[serde(deserialize_with = "deserialize_duration_from_u64_millis")]
821841
pub max_time: Option<Duration>,
822842

823843
/// The inclusive lower bound for a specific index.

src/concern/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
///
2121
/// See the documentation [here](https://docs.mongodb.com/manual/reference/read-concern/) for more
2222
/// information about read concerns.
23-
#[derive(Clone, Debug, Serialize, PartialEq)]
23+
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
2424
#[non_exhaustive]
2525
pub struct ReadConcern {
2626
/// The level of the read concern.
@@ -70,7 +70,7 @@ impl From<ReadConcernLevel> for ReadConcern {
7070
///
7171
/// See the documentation [here](https://docs.mongodb.com/manual/reference/read-concern/) for more
7272
/// information about read concerns.
73-
#[derive(Debug, Clone, PartialEq)]
73+
#[derive(Clone, Debug, PartialEq)]
7474
#[non_exhaustive]
7575
pub enum ReadConcernLevel {
7676
/// See the specific documentation for this read concern level [here](https://docs.mongodb.com/manual/reference/read-concern-local/).
@@ -113,6 +113,13 @@ impl ReadConcernLevel {
113113
}
114114
}
115115

116+
impl<'de> Deserialize<'de> for ReadConcernLevel {
117+
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> std::result::Result<Self, D::Error> {
118+
let s = String::deserialize(deserializer)?;
119+
Ok(ReadConcernLevel::from_str(&s))
120+
}
121+
}
122+
116123
impl Serialize for ReadConcernLevel {
117124
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
118125
where

0 commit comments

Comments
 (0)