Skip to main content

firestore/db/
transform_models.rs

1use crate::errors::*;
2use crate::FirestoreValue;
3
4use crate::timestamp_utils::from_timestamp;
5use crate::FirestoreInstant;
6use rsb_derive::Builder;
7
8/// The result of a Firestore write operation (create, update, delete).
9///
10/// This struct provides information about the outcome of a write, such as the
11/// document's update time and the results of any field transformations that were applied.
12#[derive(Debug, PartialEq, Clone, Builder)]
13pub struct FirestoreWriteResult {
14    /// The time at which the document was last updated after this write operation.
15    ///
16    /// This is `None` if the write operation did not result in a changed document
17    /// (e.g., deleting a non-existent document, or an update that didn't change any values).
18    pub update_time: Option<FirestoreInstant>,
19    /// A list of values that are the result of applying field transformations.
20    ///
21    /// Each [`FirestoreValue`] in this list corresponds to a
22    /// [`FirestoreFieldTransform`] applied in the write request.
23    /// The order of results matches the order of transformations in the request.
24    /// For example, if an `Increment` transform was used, this would contain the new
25    /// value of the incremented field.
26    pub transform_results: Vec<FirestoreValue>,
27}
28
29impl TryInto<FirestoreWriteResult> for gcloud_sdk::google::firestore::v1::WriteResult {
30    type Error = FirestoreError;
31
32    fn try_into(self) -> Result<FirestoreWriteResult, Self::Error> {
33        Ok(FirestoreWriteResult::new(
34            self.transform_results
35                .into_iter()
36                .map(FirestoreValue::from)
37                .collect(),
38        )
39        .opt_update_time(self.update_time.map(from_timestamp).transpose()?))
40    }
41}
42
43/// Represents a transformation to apply to a specific field within a document.
44///
45/// Field transformations allow for atomic, server-side modifications of document fields,
46/// such as incrementing a number, setting a field to the server's timestamp, or
47/// manipulating array elements.
48#[derive(Debug, PartialEq, Clone, Builder)]
49pub struct FirestoreFieldTransform {
50    /// The dot-separated path to the field to transform (e.g., "user.profile.age").
51    pub field: String,
52    /// The type of transformation to apply.
53    pub transform_type: FirestoreFieldTransformType,
54}
55
56impl TryInto<gcloud_sdk::google::firestore::v1::document_transform::FieldTransform>
57    for FirestoreFieldTransform
58{
59    type Error = FirestoreError;
60
61    fn try_into(
62        self,
63    ) -> Result<gcloud_sdk::google::firestore::v1::document_transform::FieldTransform, Self::Error>
64    {
65        Ok(
66            gcloud_sdk::google::firestore::v1::document_transform::FieldTransform {
67                field_path: self.field,
68                transform_type: Some(self.transform_type.try_into()?),
69            },
70        )
71    }
72}
73
74/// Defines the specific type of transformation to apply to a field.
75#[derive(Debug, PartialEq, Clone)]
76pub enum FirestoreFieldTransformType {
77    /// Sets the field to a server-generated value, such as the request timestamp.
78    SetToServerValue(FirestoreTransformServerValue),
79    /// Atomically increments the field's numeric value by the given `FirestoreValue` (which must be an integer or double).
80    Increment(FirestoreValue),
81    /// Atomically sets the field to the maximum of its current value and the given `FirestoreValue`.
82    Maximum(FirestoreValue),
83    /// Atomically sets the field to the minimum of its current value and the given `FirestoreValue`.
84    Minimum(FirestoreValue),
85    /// Appends the given elements to an array field, but only if they are not already present.
86    /// The `Vec<FirestoreValue>` contains the elements to append.
87    AppendMissingElements(Vec<FirestoreValue>),
88    /// Removes all instances of the given elements from an array field.
89    /// The `Vec<FirestoreValue>` contains the elements to remove.
90    RemoveAllFromArray(Vec<FirestoreValue>),
91}
92
93impl TryInto<gcloud_sdk::google::firestore::v1::document_transform::field_transform::TransformType>
94    for FirestoreFieldTransformType
95{
96    type Error = FirestoreError;
97
98    fn try_into(
99        self,
100    ) -> Result<
101        gcloud_sdk::google::firestore::v1::document_transform::field_transform::TransformType,
102        Self::Error,
103    > {
104        Ok(match self {
105            FirestoreFieldTransformType::SetToServerValue(FirestoreTransformServerValue::Unspecified) => {
106                gcloud_sdk::google::firestore::v1::document_transform::field_transform::TransformType::SetToServerValue(
107                    gcloud_sdk::google::firestore::v1::document_transform::field_transform::ServerValue::Unspecified as i32
108                )
109            },
110            FirestoreFieldTransformType::SetToServerValue(FirestoreTransformServerValue::RequestTime) => {
111                gcloud_sdk::google::firestore::v1::document_transform::field_transform::TransformType::SetToServerValue(
112                    gcloud_sdk::google::firestore::v1::document_transform::field_transform::ServerValue::RequestTime as i32
113                )
114            },
115            FirestoreFieldTransformType::Increment(value) => {
116                gcloud_sdk::google::firestore::v1::document_transform::field_transform::TransformType::Increment(
117                    value.value
118                )
119            },
120            FirestoreFieldTransformType::Maximum(value) => {
121                gcloud_sdk::google::firestore::v1::document_transform::field_transform::TransformType::Maximum(
122                    value.value
123                )
124            },
125            FirestoreFieldTransformType::Minimum(value) => {
126                gcloud_sdk::google::firestore::v1::document_transform::field_transform::TransformType::Minimum(
127                    value.value
128                )
129            },
130            FirestoreFieldTransformType::AppendMissingElements(value) => {
131                gcloud_sdk::google::firestore::v1::document_transform::field_transform::TransformType::AppendMissingElements(
132                    gcloud_sdk::google::firestore::v1::ArrayValue {
133                        values: value.into_iter().map( | s| s.value).collect()
134                    }
135                )
136            },
137            FirestoreFieldTransformType::RemoveAllFromArray(value) => {
138                gcloud_sdk::google::firestore::v1::document_transform::field_transform::TransformType::RemoveAllFromArray(
139                    gcloud_sdk::google::firestore::v1::ArrayValue {
140                        values: value.into_iter().map( | s| s.value).collect()
141                    }
142                )
143            },
144        })
145    }
146}
147
148/// Specifies a server-generated value for a field transformation.
149#[derive(Debug, Eq, PartialEq, Clone)]
150pub enum FirestoreTransformServerValue {
151    /// The server value is unspecified. This typically should not be used directly.
152    Unspecified,
153    /// Sets the field to the timestamp of when the server processes the request.
154    /// This is commonly used for `createdAt` or `updatedAt` fields.
155    RequestTime,
156}