azure_cosmos_mirror/operations/
replace_document.rs

1use crate::cosmos_entity::{add_as_partition_key_header_serialized, serialize_partition_key};
2use crate::headers::from_headers::*;
3use crate::prelude::*;
4use crate::resources::document::DocumentAttributes;
5use crate::ResourceQuota;
6
7use azure_core::headers::session_token_from_headers;
8use azure_core::prelude::*;
9use azure_core::Response as HttpResponse;
10use azure_core::SessionToken;
11use serde::Serialize;
12use time::OffsetDateTime;
13
14operation! {
15    ReplaceDocument<D: Serialize + Send + 'static>,
16    client: DocumentClient,
17    document: D,
18    ?indexing_directive: IndexingDirective,
19    ?if_match_condition: IfMatchCondition,
20    ?if_modified_since: IfModifiedSince,
21    ?allow_tentative_writes: TentativeWritesAllowance,
22    ?consistency_level: ConsistencyLevel,
23    #[skip]
24    partition_key: String
25}
26
27impl<D: Serialize + Send + 'static> ReplaceDocumentBuilder<D> {
28    pub fn partition_key<T: Serialize>(&mut self, partition_key: &T) -> azure_core::Result<()> {
29        self.partition_key = Some(serialize_partition_key(partition_key)?);
30        Ok(())
31    }
32
33    pub fn into_future(self) -> ReplaceDocument {
34        Box::pin(async move {
35            let mut request = self.client.document_request(azure_core::Method::Put);
36
37            let partition_key = self
38                .partition_key
39                .as_deref()
40                .unwrap_or_else(|| self.client.partition_key_serialized());
41            add_as_partition_key_header_serialized(partition_key, &mut request);
42
43            request.insert_headers(&self.indexing_directive.unwrap_or_default());
44            request.insert_headers(&self.if_match_condition);
45            request.insert_headers(&self.if_modified_since);
46            if let Some(cl) = &self.consistency_level {
47                request.insert_headers(cl);
48            }
49            request.insert_headers(&self.allow_tentative_writes.unwrap_or_default());
50
51            let serialized = azure_core::to_json(&self.document)?;
52            request.set_body(serialized);
53
54            let response = self
55                .client
56                .cosmos_client()
57                .pipeline()
58                .send(
59                    self.context.clone().insert(ResourceType::Documents),
60                    &mut request,
61                )
62                .await?;
63
64            ReplaceDocumentResponse::try_from(response).await
65        })
66    }
67}
68
69#[derive(Debug, Clone)]
70pub struct ReplaceDocumentResponse {
71    pub document_attributes: DocumentAttributes,
72    pub content_location: Option<String>,
73    pub last_state_change: OffsetDateTime,
74    pub resource_quota: Vec<ResourceQuota>,
75    pub resource_usage: Vec<ResourceQuota>,
76    pub lsn: u64,
77    pub schema_version: String,
78    pub alt_content_path: String,
79    pub content_path: String,
80    pub quorum_acked_lsn: Option<u64>,
81    pub current_write_quorum: Option<u64>,
82    pub current_replica_set_size: Option<u64>,
83    pub role: u32,
84    pub global_committed_lsn: u64,
85    pub number_of_read_regions: u32,
86    pub transport_request_id: u64,
87    pub cosmos_llsn: u64,
88    pub cosmos_quorum_acked_llsn: Option<u64>,
89    pub session_token: SessionToken,
90    pub charge: f64,
91    pub service_version: String,
92    pub activity_id: uuid::Uuid,
93    pub gateway_version: String,
94    pub date: OffsetDateTime,
95}
96
97impl ReplaceDocumentResponse {
98    pub async fn try_from(response: HttpResponse) -> azure_core::Result<Self> {
99        let (_status_code, headers, body) = response.deconstruct();
100        let body = body.collect().await?;
101        let document_attributes = serde_json::from_slice(&*body)?;
102
103        Ok(Self {
104            content_location: content_location_from_headers(&headers)?,
105            last_state_change: last_state_change_from_headers(&headers)?,
106            resource_quota: resource_quota_from_headers(&headers)?,
107            resource_usage: resource_usage_from_headers(&headers)?,
108            lsn: lsn_from_headers(&headers)?,
109            schema_version: schema_version_from_headers(&headers)?,
110            alt_content_path: alt_content_path_from_headers(&headers)?,
111            content_path: content_path_from_headers(&headers)?,
112            quorum_acked_lsn: quorum_acked_lsn_from_headers_optional(&headers)?,
113            current_write_quorum: current_write_quorum_from_headers_optional(&headers)?,
114            current_replica_set_size: current_replica_set_size_from_headers_optional(&headers)?,
115            role: role_from_headers(&headers)?,
116            global_committed_lsn: global_committed_lsn_from_headers(&headers)?,
117            number_of_read_regions: number_of_read_regions_from_headers(&headers)?,
118            transport_request_id: transport_request_id_from_headers(&headers)?,
119            cosmos_llsn: cosmos_llsn_from_headers(&headers)?,
120            cosmos_quorum_acked_llsn: cosmos_quorum_acked_llsn_from_headers_optional(&headers)?,
121            session_token: session_token_from_headers(&headers)?,
122            charge: request_charge_from_headers(&headers)?,
123            service_version: service_version_from_headers(&headers)?,
124            activity_id: activity_id_from_headers(&headers)?,
125            gateway_version: gateway_version_from_headers(&headers)?,
126            date: date_from_headers(&headers)?,
127            document_attributes,
128        })
129    }
130}