Skip to content

Commit 719beab

Browse files
authored
RUST-1897 Fluent options parsing (#1061)
1 parent f47d16e commit 719beab

File tree

20 files changed

+333
-319
lines changed

20 files changed

+333
-319
lines changed

src/action.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Action builder types.
22
33
mod aggregate;
4+
mod client_options;
45
mod count;
56
mod create_collection;
67
mod create_index;
@@ -32,6 +33,7 @@ use std::{future::IntoFuture, marker::PhantomData, ops::Deref};
3233

3334
pub use aggregate::Aggregate;
3435
use bson::Document;
36+
pub use client_options::ParseConnectionString;
3537
pub use count::{CountDocuments, EstimatedDocumentCount};
3638
pub use create_collection::CreateCollection;
3739
pub use create_index::CreateIndex;

src/action/client_options.rs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
use crate::{
2+
client::options::{ClientOptions, ConnectionString, ResolverConfig},
3+
error::{Error, Result},
4+
};
5+
6+
impl ClientOptions {
7+
/// Parses a MongoDB connection string (as either a `&str` or a [`ConnectionString`]) into a
8+
/// [`ClientOptions`] struct. If the string is malformed or one of the options has an
9+
/// invalid value, an error will be returned.
10+
///
11+
/// In the case that "mongodb+srv" is used, SRV and TXT record lookups will be done as
12+
/// part of this method.
13+
///
14+
/// The format of a MongoDB connection string is described [here](https://www.mongodb.com/docs/manual/reference/connection-string/#connection-string-formats).
15+
///
16+
/// Note that [default_database](ClientOptions::default_database) will be set from
17+
/// `/defaultauthdb` in connection string.
18+
///
19+
/// The following options are supported in the options query string:
20+
///
21+
/// * `appName`: maps to the `app_name` field
22+
/// * `authMechanism`: maps to the `mechanism` field of the `credential` field
23+
/// * `authSource`: maps to the `source` field of the `credential` field
24+
/// * `authMechanismProperties`: maps to the `mechanism_properties` field of the `credential`
25+
/// field
26+
/// * `compressors`: maps to the `compressors` field
27+
/// * `connectTimeoutMS`: maps to the `connect_timeout` field
28+
/// * `direct`: maps to the `direct` field
29+
/// * `heartbeatFrequencyMS`: maps to the `heartbeat_frequency` field
30+
/// * `journal`: maps to the `journal` field of the `write_concern` field
31+
/// * `localThresholdMS`: maps to the `local_threshold` field
32+
/// * `maxIdleTimeMS`: maps to the `max_idle_time` field
33+
/// * `maxStalenessSeconds`: maps to the `max_staleness` field of the `selection_criteria`
34+
/// field
35+
/// * `maxPoolSize`: maps to the `max_pool_size` field
36+
/// * `minPoolSize`: maps to the `min_pool_size` field
37+
/// * `readConcernLevel`: maps to the `read_concern` field
38+
/// * `readPreferenceField`: maps to the ReadPreference enum variant of the
39+
/// `selection_criteria` field
40+
/// * `readPreferenceTags`: maps to the `tags` field of the `selection_criteria` field. Note
41+
/// that this option can appear more than once; each instance will be mapped to a separate
42+
/// tag set
43+
/// * `replicaSet`: maps to the `repl_set_name` field
44+
/// * `retryWrites`: not yet implemented
45+
/// * `retryReads`: maps to the `retry_reads` field
46+
/// * `serverSelectionTimeoutMS`: maps to the `server_selection_timeout` field
47+
/// * `socketTimeoutMS`: unsupported, does not map to any field
48+
/// * `ssl`: an alias of the `tls` option
49+
/// * `tls`: maps to the TLS variant of the `tls` field`.
50+
/// * `tlsInsecure`: relaxes the TLS constraints on connections being made; currently is just
51+
/// an alias of `tlsAllowInvalidCertificates`, but more behavior may be added to this option
52+
/// in the future
53+
/// * `tlsAllowInvalidCertificates`: maps to the `allow_invalidCertificates` field of the
54+
/// `tls` field
55+
/// * `tlsCAFile`: maps to the `ca_file_path` field of the `tls` field
56+
/// * `tlsCertificateKeyFile`: maps to the `cert_key_file_path` field of the `tls` field
57+
/// * `w`: maps to the `w` field of the `write_concern` field
58+
/// * `waitQueueTimeoutMS`: unsupported, does not map to any field
59+
/// * `wTimeoutMS`: maps to the `w_timeout` field of the `write_concern` field
60+
/// * `zlibCompressionLevel`: maps to the `level` field of the `Compressor::Zlib` variant
61+
/// (which requires the `zlib-compression` feature flag) of the
62+
/// [`Compressor`](crate::compression::compressors::Compressor) enum
63+
///
64+
/// `await` will return `Result<ClientOptions>`.
65+
pub fn parse<C, E>(conn_str: C) -> ParseConnectionString
66+
where
67+
C: TryInto<ConnectionString, Error = E>,
68+
E: Into<Error>,
69+
{
70+
ParseConnectionString {
71+
conn_str: conn_str.try_into().map_err(Into::into),
72+
resolver_config: None,
73+
}
74+
}
75+
}
76+
77+
fn _assert_accept_str() {
78+
let _ = ClientOptions::parse("foo");
79+
}
80+
81+
#[allow(unreachable_code, clippy::diverging_sub_expression)]
82+
fn _assert_accept_conn_str() {
83+
let _c: ConnectionString = todo!();
84+
let _ = ClientOptions::parse(_c);
85+
}
86+
87+
/// Parses a MongoDB connection string into a [`ClientOptions`] struct. Construct with
88+
/// [`ClientOptions::parse`].
89+
#[must_use]
90+
pub struct ParseConnectionString {
91+
pub(crate) conn_str: Result<ConnectionString>,
92+
pub(crate) resolver_config: Option<ResolverConfig>,
93+
}
94+
95+
impl ParseConnectionString {
96+
/// In the case that "mongodb+srv" is used, SRV and TXT record lookups will be done using the
97+
/// provided `ResolverConfig` as part of this method.
98+
pub fn resolver_config(mut self, value: ResolverConfig) -> Self {
99+
self.resolver_config = Some(value);
100+
self
101+
}
102+
}
103+
104+
// Action impl in src/client/options/parse.rs.

src/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ impl Client {
140140
/// See the documentation on
141141
/// [`ClientOptions::parse`](options/struct.ClientOptions.html#method.parse) for more details.
142142
pub async fn with_uri_str(uri: impl AsRef<str>) -> Result<Self> {
143-
let options = ClientOptions::parse_uri(uri.as_ref(), None).await?;
143+
let options = ClientOptions::parse(uri.as_ref()).await?;
144144

145145
Client::with_options(options)
146146
}

src/client/csfle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl ClientState {
6060
let uri = opts
6161
.extra_option(&EO_MONGOCRYPTD_URI)?
6262
.unwrap_or(Self::MONGOCRYPTD_DEFAULT_URI);
63-
let mut options = crate::options::ClientOptions::parse_uri(uri, None).await?;
63+
let mut options = crate::options::ClientOptions::parse(uri).await?;
6464
options.server_selection_timeout = Some(Self::MONGOCRYPTD_SERVER_SELECTION_TIMEOUT);
6565
Some(Client::with_options(options)?)
6666
} else {

0 commit comments

Comments
 (0)