diff --git a/driver/src/selection_criteria.rs b/driver/src/selection_criteria.rs
index a2d80166a..647a00d9c 100644
--- a/driver/src/selection_criteria.rs
+++ b/driver/src/selection_criteria.rs
@@ -280,6 +280,43 @@ pub struct HedgedReadOptions {
}
impl ReadPreference {
+ /// Creates a `ReadPreference::Primary`. Reads will only be routed to the primary.
+ pub fn primary() -> Self {
+ Self::Primary
+ }
+
+ /// Creates a `ReadPreference::Secondary` with the given options. Reads will only be routed to a
+ /// secondary.
+ pub fn secondary(options: impl Into>) -> Self {
+ Self::Secondary {
+ options: options.into(),
+ }
+ }
+
+ /// Creates a `ReadPreference::PrimaryPreferred` with the given options. Reads will be routed to
+ /// the primary if it's available, and fall back to the secondaries if not.
+ pub fn primary_preferred(options: impl Into >) -> Self {
+ Self::PrimaryPreferred {
+ options: options.into(),
+ }
+ }
+
+ /// Creates a `ReadPreference::SecondaryPreferred` with the given options. Reads will be routed
+ /// to a secondary if one is available, and fall back to the primary if not.
+ pub fn secondary_preferred(options: impl Into >) -> Self {
+ Self::SecondaryPreferred {
+ options: options.into(),
+ }
+ }
+
+ /// Creates a `ReadPreference::Nearest` with the given options. Reads will be routed to the node
+ /// with the least network latency regardless of whether it's the primary or a secondary.
+ pub fn nearest(options: impl Into >) -> Self {
+ Self::Nearest {
+ options: options.into(),
+ }
+ }
+
pub(crate) fn mode(&self) -> &'static str {
match self {
Self::Primary => "primary",
@@ -356,6 +393,8 @@ pub type TagSet = HashMap;
#[cfg(test)]
mod test {
+ use std::time::Duration;
+
use super::{HedgedReadOptions, ReadPreference, ReadPreferenceOptions};
use crate::bson::doc;
@@ -376,4 +415,36 @@ mod test {
doc! { "mode": "secondary", "hedge": { "enabled": true } }
);
}
+
+ #[test]
+ fn constructors() {
+ assert_eq!(ReadPreference::primary(), ReadPreference::Primary);
+
+ assert_eq!(
+ ReadPreference::secondary(None),
+ ReadPreference::Secondary { options: None }
+ );
+ assert_eq!(
+ ReadPreference::primary_preferred(None),
+ ReadPreference::PrimaryPreferred { options: None }
+ );
+ assert_eq!(
+ ReadPreference::secondary_preferred(None),
+ ReadPreference::SecondaryPreferred { options: None }
+ );
+ assert_eq!(
+ ReadPreference::nearest(None),
+ ReadPreference::Nearest { options: None }
+ );
+
+ let options = ReadPreferenceOptions::builder()
+ .max_staleness(Duration::from_secs(120))
+ .build();
+ assert_eq!(
+ ReadPreference::nearest(options.clone()),
+ ReadPreference::Nearest {
+ options: Some(options)
+ }
+ );
+ }
}