1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
//! Contains all of the types needed to specify options to MongoDB operations.
//!
//! Most of the options structs in this module use the
//! [`typed-builder`](https://crates.io/crates/typed-builder) crate to derive a type-safe builder
//! API on them. For example, to create an instance of
//! [`FindOptions`](struct.FindOptions.html) with only `limit` and `batch_size` set, the builder
//! API can be used as follows:
//!
//! ```rust
//! use mongodb::options::FindOptions;
//!
//! let options = FindOptions::builder()
//! .limit(20)
//! .batch_size(5)
//! .build();
//! ```
pub use crate::{
client::{auth::*, options::*},
coll::options::*,
collation::*,
concern::*,
db::options::*,
index::options::*,
selection_criteria::*,
};
/// Updates an options struct with the read preference/read concern/write concern of a
/// client/database/collection.
macro_rules! resolve_options {
($obj:expr, $opts:expr, [$( $field:ident ),+] ) => {
$(
if let Some(option) = $obj.$field() {
if !$opts
.as_ref()
.map(|opts| opts.$field.is_some())
.unwrap_or(false)
{
$opts.get_or_insert_with(Default::default).$field = Some(option.clone());
}
}
)+
};
}
/// Merges the options from src into dst.
macro_rules! merge_options {
($src:expr, $dst:expr, [$( $field:ident ),+] ) => {
$(
if let Some(ref option) = $src.$field {
if !$dst.$field.is_some() {
$dst.$field = Some(option.clone());
}
}
)+
};
}
/// Updates the read concern of an options struct. If a transaction is starting or in progress,
/// return an error if a read concern was specified for the operation. Otherwise, inherit the read
/// concern from the collection/database.
macro_rules! resolve_read_concern_with_session {
($obj:expr, $opts:expr, $session:expr) => {{
resolve_rw_concern_with_session!($obj, $opts, $session, read_concern, "read")
}};
}
/// Updates the read concern of an options struct. If a transaction is starting or in progress,
/// return an error if a write concern was specified for the operation. Otherwise, inherit the write
/// concern from the collection/database.
macro_rules! resolve_write_concern_with_session {
($obj:expr, $opts:expr, $session:expr) => {{
resolve_rw_concern_with_session!($obj, $opts, $session, write_concern, "write")
}};
}
macro_rules! resolve_rw_concern_with_session {
($obj:expr, $opts:expr, $session:expr, $concern:ident, $name:expr) => {{
if let Some(session) = $session {
match session.transaction.state {
TransactionState::Starting | TransactionState::InProgress => {
if $opts
.as_ref()
.map(|opts| opts.$concern.is_some())
.unwrap_or(false)
{
return Err(ErrorKind::InvalidArgument {
message: format!(
"Cannot set {} concern after starting a transaction",
$name
),
}
.into());
}
}
_ => {
resolve_options!($obj, $opts, [$concern]);
}
}
} else {
resolve_options!($obj, $opts, [$concern]);
}
let result: Result<()> = Ok(());
result
}};
}
/// Updates the selection criteria of an options struct. If a transaction is starting or in progress
/// and the selection criteria is not configured directly on the operation, inherit the selection
/// criteria from the transaction options. Otherwise, use the selection criteria defined on the
/// operation or inherit it from the collection/database.
macro_rules! resolve_selection_criteria_with_session {
($obj:expr, $opts:expr, $session:expr) => {{
if let Some(session) = $session {
match session.transaction.state {
TransactionState::Starting | TransactionState::InProgress => {
if let Some(ref options) = session.transaction.options {
if let Some(ref selection_criteria) = options.selection_criteria {
if $opts
.as_ref()
.map(|opts| opts.selection_criteria.is_none())
.unwrap_or(true)
{
$opts
.get_or_insert_with(Default::default)
.selection_criteria = Some(selection_criteria.clone());
}
}
}
}
_ => {
resolve_options!($obj, $opts, [selection_criteria]);
}
}
} else {
resolve_options!($obj, $opts, [selection_criteria]);
}
let result: Result<()> = Ok(());
result
}};
}