Skip to content

Commit d560197

Browse files
committed
(cherry picked from commit bd90347)
1 parent f708a00 commit d560197

File tree

2 files changed

+249
-6
lines changed

2 files changed

+249
-6
lines changed

source/faq.txt

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
.. _rust-faq:
2+
3+
===
4+
FAQ
5+
===
6+
7+
.. facet::
8+
:name: genre
9+
:values: reference
10+
11+
.. meta::
12+
:keywords: code example, connection error, question, help
13+
14+
.. contents:: On this page
15+
:local:
16+
:backlinks: none
17+
:depth: 1
18+
:class: singlecol
19+
20+
On this page, you can find frequently asked questions and their corresponding answers.
21+
22+
.. tip::
23+
24+
If you can't find an answer to your question on this page, see the
25+
:ref:`rust-issues-and-help` page for information on how to report issues.
26+
27+
Why Do I Get Errors While Connecting to MongoDB?
28+
------------------------------------------------
29+
30+
If you have trouble connecting to a MongoDB deployment, see the
31+
:ref:`rust-connection-troubleshooting` guide for possible solutions.
32+
33+
.. _rust-faq-connection-pool:
34+
35+
How Does Connection Pooling Work in the Rust Driver?
36+
----------------------------------------------------
37+
38+
Each server in your MongoDB cluster maintains a connection pool. You can access or
39+
manage the behavior of the connection pool by using an instance of a `Client
40+
<{+api+}/struct.Client.html>`__. Connection pools open sockets on demand to support
41+
concurrent operations in your multi-threaded application.
42+
43+
You can configure the following connection pool features:
44+
45+
- Maximum and minimum size, set by the ``max_pool_size`` and ``min_pool_size`` options
46+
- Maximum number of connections that the pool creates in parallel, set by the ``max_connecting``
47+
option
48+
- Maximum idle time, set by the ``max_idle_time`` option
49+
50+
For more information about connection pooling, see the :ref:`rust-performance-pool`
51+
section of the Performance Considerations guide.
52+
53+
How Do I Convert Between BSON and Rust Types?
54+
---------------------------------------------
55+
56+
The {+driver-short+} and the BSON library use the Serde framework to perform
57+
conversions between custom Rust types and BSON. You can add the ``serde``
58+
crate to your ``Cargo.toml`` file to access the functionality of the Serde framework.
59+
For instructions on adding this crate, see `serde <https://crates.io/crates/serde>`__
60+
in the crates registry.
61+
62+
After you add the crate to your application, you can model the documents in a collection
63+
by using a custom type instead of a BSON document. The following example includes the ``derive``
64+
attribute before the ``Vegetable`` struct definition, which instructs the driver to
65+
perform the following actions when needed:
66+
67+
- Serialize the struct, which converts the struct to BSON
68+
- Deserialize BSON, which converts BSON data to your struct
69+
70+
.. code-block:: rust
71+
:copyable: true
72+
73+
#[derive(Serialize, Deserialize)]
74+
struct Vegetable {
75+
// Add struct fields here
76+
}
77+
78+
You can then create a ``Collection`` instance with your custom struct type as its
79+
generic type parameter. The following example assigns a ``Collection`` instance
80+
parameterized with the ``Vegetable`` type to the ``my_coll`` variable:
81+
82+
.. code-block:: rust
83+
:copyable: true
84+
85+
let my_coll: Collection<Vegetable> = client.database("db").collection("vegetables");
86+
87+
For more information about converting between BSON and Rust types, see the
88+
:ref:`rust-serialization` guide and the :website:`Structuring Data with Serde in Rust
89+
</developer/languages/rust/serde-improvements/>` MongoDB Developer Center article.
90+
91+
How Do I Fix Unsatisfied Trait Bounds Errors?
92+
---------------------------------------------
93+
94+
Trait bounds allow methods to restrict which types they accept as parameters
95+
and what functionality those types must implement. For example, if you define
96+
a method that accepts a generic type parameter and prints its value, the parameter
97+
must implement the ``Display`` trait for printing purposes. The following example
98+
defines the ``printer()`` method and specifies that its parameter must implement
99+
``Display``:
100+
101+
.. code-block:: rust
102+
:copyable: true
103+
104+
fn printer<T: Display>(t: T) {
105+
println!("{}", t);
106+
}
107+
108+
When calling a method on a data type, you might encounter an error stating that
109+
the method's trait bounds are not satisfied. For example, the driver might raise
110+
the following error message when you call the ``try_next()`` method on a ``Cursor``
111+
instance:
112+
113+
.. code-block:: none
114+
:copyable: false
115+
116+
error[E0599]: the method `try_next` exists for struct `mongodb::Cursor<T>`,
117+
but its trait bounds were not satisfied
118+
119+
The ``Cursor<T>`` type only implements the ``Stream`` trait, which is required to access
120+
the ``try_next()`` method, if the trait bounds for ``T`` are satisfied. Namely, ``T``
121+
must implement the ``DeserializeOwned`` trait, as specified in the `Cursor
122+
<{+api+}/struct.Cursor.html>`__ API documentation. The following example replicates the
123+
preceding error message by defining a custom ``Actor`` struct to model documents in the
124+
``actors`` collection. However, this struct does not implement the ``DeserializeOwned`` trait,
125+
and using the ``try_next()`` method to iterate over ``Actor`` instances causes an error:
126+
127+
.. code-block:: rust
128+
:copyable: true
129+
130+
struct Actor {
131+
name: String,
132+
}
133+
134+
// Add setup code here
135+
136+
let my_coll: Collection<Actor> = client.database("db").collection("actors");
137+
let mut cursor = my_coll.find(None, None).await?;
138+
while let Some(result) = cursor.try_next().await? {
139+
println!("{:?}", result);
140+
};
141+
142+
To resolve the trait bounds error, identify the data type over which the cursor
143+
iterates and ensure that this data type implements the ``DeserializeOwned`` trait.
144+
You can use the ``derive`` attribute to apply the required trait bound.
145+
146+
.. note:: Deserialize and DeserializeOwned Traits
147+
148+
The ``serde`` crate provides derive macros to generate the implementation of
149+
certain traits, including the ``Deserialize`` trait. However, this crate does not
150+
offer a derive macro for the ``DeserializeOwned`` trait. Data types that implement
151+
``Deserialize`` without lifetime restrictions automatically implement ``DeserializeOwned``,
152+
so you can implement ``Deserialize`` to fulfill the ``DeserializeOwned`` trait bound.
153+
154+
The following example adjusts the ``Actor`` struct definition to implement ``Deserialize``:
155+
156+
.. code-block:: rust
157+
:copyable: true
158+
159+
#[derive(Deserialize)]
160+
struct Actor {
161+
name: String,
162+
}
163+
164+
For more information about trait bounds, see the following resources:
165+
166+
- :community-forum:`Cursor trait bounds question <t/rust-driver-help-writing-a-generic-find-method/168846>`
167+
in the Community Forums
168+
- `Bounds <https://doc.rust-lang.org/rust-by-example/generics/bounds.html>`__ in the
169+
Rust language documentation
170+
- `Derive <https://doc.rust-lang.org/rust-by-example/trait/derive.html>`__
171+
in the Rust language documentation
172+
173+
How Do I Process a Value Wrapped in a Result or Option Enum?
174+
------------------------------------------------------------
175+
176+
Rust provides the ``Result`` and ``Option`` enums as safeguards for your application
177+
code. Many methods offered by the {+driver-short+} return values wrapped in one of these
178+
two types.
179+
180+
The ``Result`` enum can return the following variants:
181+
182+
- ``Ok(T)``: wraps the value of the result of the operation
183+
- ``Err(E)``: wraps an error value if the operation is unsuccessful
184+
185+
For example, the ``insert_one()`` method returns a ``Result`` type to wrap either a successful
186+
response or an error.
187+
188+
To access the unwrapped result of ``insert_one()``, use the ``?`` operator. If the operation is
189+
successful, the method returns the ``Ok(InsertOneResult)`` variant of the ``Result`` enum. In this
190+
case, the ``?`` operator unwraps the ``InsertOneResult`` value and assigns it to the ``insert_one_result``
191+
variable. If the operation is unsuccessful, the method returns the ``Err(E)`` enum variant, and the
192+
``?`` operator unwraps and returns the error value. The following code demonstrates the syntax for
193+
using the ``?`` operator while handling an insert operation result:
194+
195+
.. code-block:: rust
196+
:copyable: true
197+
198+
let insert_one_result = my_coll.insert_one(doc, None).await?;
199+
200+
Alternatively, you can create a conditional to handle the unwrapped values of ``InsertOneResult``.
201+
The following code uses the ``match`` keyword to process the ``insert_one()`` result:
202+
203+
.. code-block:: rust
204+
:copyable: true
205+
206+
let insert_one_result = my_coll.insert_one(doc, None).await;
207+
208+
match insert_one_result {
209+
Ok(val) => {
210+
println!("Document inserted with ID: {}", val.inserted_id);
211+
},
212+
Err(err) => {
213+
println!("Operation not successful");
214+
}
215+
}
216+
217+
The ``Option`` enum can return the following variants:
218+
219+
- ``None``: represents an empty value returned by an operation
220+
- ``Some(T)``: wraps a non-empty return value
221+
222+
Some {+driver-short+} methods return an ``Option`` type, such as the ``read_concern()``
223+
method. This method returns an ``Option`` that wraps either an empty value, if no read
224+
concern exists, or a ``ReadConcern`` value.
225+
226+
To access the result of ``read_concern()``, you can use the same ``match`` syntax as shown
227+
in the preceding example to process the ``None`` and ``Some(T)`` variants. Alternatively, you
228+
can use the ``if let`` syntax to process only the ``Some(T)`` variant. The following code unwraps
229+
and prints the non-empty ``read_concern()`` return value, if it exists:
230+
231+
.. code-block:: rust
232+
:copyable: true
233+
234+
if let Some(rc) = my_coll.read_concern() {
235+
println!("Read concern: {:?}", rc);
236+
}
237+
238+
For more information about the ``Result`` and ``Option`` enums, see the following
239+
resources in the Rust language documentation:
240+
241+
- `Result <https://doc.rust-lang.org/std/result/enum.Result.html>`__
242+
- `Option <https://doc.rust-lang.org/std/option/enum.Option.html>`__
243+
- `? Operator <https://doc.rust-lang.org/rust-by-example/std/result/question_mark.html>`__
244+
- `Concise Control Flow with if let <https://doc.rust-lang.org/book/ch06-03-if-let.html>`__

source/index.txt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@
1212
/usage-examples
1313
/fundamentals
1414
API Documentation <{+api+}/>
15+
/faq
1516
/connection-troubleshooting
1617
/op-error-handling
1718
/issues-and-help
1819
/compatibility
1920
View the Source <https://github.com/mongodb/mongo-rust-driver>
2021

21-
..
22-
/faq
2322

2423
Introduction
2524
------------
@@ -64,11 +63,11 @@ API
6463
For detailed information about types and methods in the {+driver-long+},
6564
see the `API documentation <{+api+}/>`__.
6665

67-
.. FAQ
68-
.. ---
66+
FAQ
67+
---
6968

70-
.. For answers to commonly asked questions about the {+driver-long+}, see
71-
.. the :ref:`rust-faq` section.
69+
For answers to commonly asked questions about the {+driver-long+}, see
70+
the :ref:`rust-faq` section.
7271

7372
Connection Troubleshooting
7473
--------------------------

0 commit comments

Comments
 (0)