azure_data_cosmos/options/
mod.rs1use crate::constants;
5use crate::models::ThroughputProperties;
6use azure_core::http::headers::{AsHeaders, HeaderName, HeaderValue};
7use azure_core::http::{headers, ClientMethodOptions, ClientOptions, Etag};
8use std::convert::Infallible;
9use std::fmt;
10use std::fmt::Display;
11
12#[derive(Clone, Default)]
14pub struct CosmosClientOptions {
15 pub client_options: ClientOptions,
16}
17
18#[derive(Clone, Default)]
20pub struct CreateContainerOptions<'a> {
21 pub method_options: ClientMethodOptions<'a>,
22 pub throughput: Option<ThroughputProperties>,
23}
24
25#[derive(Clone, Default)]
27pub struct ReplaceContainerOptions<'a> {
28 pub method_options: ClientMethodOptions<'a>,
29}
30
31#[derive(Clone, Default)]
33pub struct CreateDatabaseOptions<'a> {
34 pub method_options: ClientMethodOptions<'a>,
35 pub throughput: Option<ThroughputProperties>,
36}
37
38#[derive(Clone, Default)]
40pub struct DeleteContainerOptions<'a> {
41 pub method_options: ClientMethodOptions<'a>,
42}
43
44#[derive(Clone, Default)]
46pub struct DeleteDatabaseOptions<'a> {
47 pub method_options: ClientMethodOptions<'a>,
48}
49
50#[derive(Clone)]
54pub enum ConsistencyLevel {
55 ConsistentPrefix,
56 Eventual,
57 Session,
58 BoundedStaleness,
59 Strong,
60}
61
62impl Display for ConsistencyLevel {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 let value = match self {
65 ConsistencyLevel::ConsistentPrefix => "ConsistentPrefix",
66 ConsistencyLevel::Eventual => "Eventual",
67 ConsistencyLevel::Session => "Session",
68 ConsistencyLevel::BoundedStaleness => "BoundedStaleness",
69 ConsistencyLevel::Strong => "Strong",
70 };
71 write!(f, "{}", value)
72 }
73}
74
75#[derive(Clone)]
77pub enum IndexingDirective {
78 Default,
79 Include,
80 Exclude,
81}
82
83impl Display for IndexingDirective {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 let value = match self {
86 IndexingDirective::Default => "Default",
87 IndexingDirective::Include => "Include",
88 IndexingDirective::Exclude => "Exclude",
89 };
90 write!(f, "{}", value)
91 }
92}
93
94#[derive(Clone, Default)]
96pub struct ItemOptions<'a> {
97 pub method_options: ClientMethodOptions<'a>,
98 pub pre_triggers: Option<Vec<String>>,
102 pub post_triggers: Option<Vec<String>>,
106 pub session_token: Option<String>,
112 pub consistency_level: Option<ConsistencyLevel>,
117 pub indexing_directive: Option<IndexingDirective>,
119 pub if_match_etag: Option<Etag>,
123 pub enable_content_response_on_write: bool,
127}
128
129impl AsHeaders for ItemOptions<'_> {
130 type Error = Infallible;
131 type Iter = std::vec::IntoIter<(HeaderName, HeaderValue)>;
132
133 fn as_headers(&self) -> Result<Self::Iter, Self::Error> {
134 let mut headers = Vec::new();
135
136 if let Some(pre_triggers) = &self.pre_triggers {
137 headers.push((
138 constants::PRE_TRIGGER_INCLUDE,
139 pre_triggers.join(",").into(),
140 ));
141 }
142
143 if let Some(post_triggers) = &self.post_triggers {
144 headers.push((
145 constants::POST_TRIGGER_INCLUDE,
146 post_triggers.join(",").into(),
147 ));
148 }
149
150 if let Some(session_token) = &self.session_token {
151 headers.push((constants::SESSION_TOKEN, session_token.into()));
152 }
153
154 if let Some(consistency_level) = &self.consistency_level {
155 headers.push((
156 constants::CONSISTENCY_LEVEL,
157 consistency_level.to_string().into(),
158 ));
159 }
160
161 if let Some(indexing_directive) = &self.indexing_directive {
162 headers.push((
163 constants::INDEXING_DIRECTIVE,
164 indexing_directive.to_string().into(),
165 ));
166 }
167
168 if let Some(etag) = &self.if_match_etag {
169 headers.push((headers::IF_MATCH, etag.to_string().into()));
170 }
171
172 if !self.enable_content_response_on_write {
173 headers.push((headers::PREFER, constants::PREFER_MINIMAL));
174 }
175
176 Ok(headers.into_iter())
177 }
178}
179
180#[derive(Clone, Default)]
182pub struct QueryContainersOptions<'a> {
183 pub method_options: ClientMethodOptions<'a>,
184}
185
186#[derive(Clone, Default)]
188pub struct QueryDatabasesOptions<'a> {
189 pub method_options: ClientMethodOptions<'a>,
190}
191
192#[derive(Clone, Default)]
194pub struct QueryOptions<'a> {
195 pub method_options: ClientMethodOptions<'a>,
196
197 #[cfg(feature = "preview_query_engine")]
202 pub query_engine: Option<crate::query::QueryEngineRef>,
203}
204
205impl QueryOptions<'_> {
206 pub fn into_owned(self) -> QueryOptions<'static> {
207 QueryOptions {
208 method_options: ClientMethodOptions {
209 context: self.method_options.context.into_owned(),
210 },
211 #[cfg(feature = "preview_query_engine")]
212 query_engine: self.query_engine,
213 }
214 }
215}
216
217#[derive(Clone, Default)]
219pub struct ReadContainerOptions<'a> {
220 pub method_options: ClientMethodOptions<'a>,
221}
222
223#[derive(Clone, Default)]
225pub struct ReadDatabaseOptions<'a> {
226 pub method_options: ClientMethodOptions<'a>,
227}
228
229#[derive(Clone, Default)]
231pub struct ThroughputOptions<'a> {
232 pub method_options: ClientMethodOptions<'a>,
233}
234
235#[cfg(test)]
236mod tests {
237 use super::*;
238
239 #[test]
240 fn item_options_as_headers() {
241 let item_options = ItemOptions {
242 pre_triggers: Some(vec!["PreTrigger1".to_string(), "PreTrigger2".to_string()]),
243 post_triggers: Some(vec!["PostTrigger1".to_string(), "PostTrigger2".to_string()]),
244 session_token: Some("SessionToken".to_string()),
245 consistency_level: Some(ConsistencyLevel::Session),
246 indexing_directive: Some(IndexingDirective::Include),
247 if_match_etag: Some(Etag::from("etag_value")),
248 enable_content_response_on_write: false,
249 ..Default::default()
250 };
251
252 let headers_result: Vec<(HeaderName, HeaderValue)> =
253 item_options.as_headers().unwrap().collect();
254
255 let headers_expected: Vec<(HeaderName, HeaderValue)> = vec![
256 (
257 constants::PRE_TRIGGER_INCLUDE,
258 "PreTrigger1,PreTrigger2".into(),
259 ),
260 (
261 constants::POST_TRIGGER_INCLUDE,
262 "PostTrigger1,PostTrigger2".into(),
263 ),
264 (constants::SESSION_TOKEN, "SessionToken".into()),
265 (constants::CONSISTENCY_LEVEL, "Session".into()),
266 (constants::INDEXING_DIRECTIVE, "Include".into()),
267 (headers::IF_MATCH, "etag_value".into()),
268 (headers::PREFER, constants::PREFER_MINIMAL),
269 ];
270
271 assert_eq!(headers_result, headers_expected);
272 }
273
274 #[test]
275 fn item_options_empty_as_headers_with_content_response() {
276 let item_options = ItemOptions::default();
277
278 let headers_result: Vec<(HeaderName, HeaderValue)> =
279 item_options.as_headers().unwrap().collect();
280
281 let headers_expected: Vec<(HeaderName, HeaderValue)> =
282 vec![(headers::PREFER, constants::PREFER_MINIMAL)];
283
284 assert_eq!(headers_result, headers_expected);
285 }
286
287 #[test]
288 fn item_options_empty_as_headers() {
289 let item_options = ItemOptions {
290 enable_content_response_on_write: true,
291 ..Default::default()
292 };
293
294 let headers_result: Vec<(HeaderName, HeaderValue)> =
295 item_options.as_headers().unwrap().collect();
296
297 let headers_expected: Vec<(HeaderName, HeaderValue)> = vec![];
298
299 assert_eq!(headers_result, headers_expected);
300 }
301}