firebase_rs_sdk/data_connect/
reference.rs

1use std::sync::Arc;
2use std::time::SystemTime;
3
4use chrono::{DateTime, Utc};
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8use crate::data_connect::api::DataConnectService;
9use crate::data_connect::config::DataConnectOptions;
10
11/// Indicates where a result originated from.
12#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
13#[serde(rename_all = "UPPERCASE")]
14pub enum DataSource {
15    Cache,
16    Server,
17}
18
19impl DataSource {
20    pub fn as_str(&self) -> &'static str {
21        match self {
22            DataSource::Cache => "CACHE",
23            DataSource::Server => "SERVER",
24        }
25    }
26}
27
28/// Internal discriminant for refs.
29#[derive(Clone, Copy, Debug, PartialEq, Eq)]
30pub enum OperationType {
31    Query,
32    Mutation,
33}
34
35/// Common state for query & mutation references.
36#[derive(Clone, Debug)]
37pub struct OperationRef {
38    pub(crate) service: Arc<DataConnectService>,
39    pub(crate) name: Arc<str>,
40    pub(crate) variables: Value,
41    #[allow(dead_code)]
42    pub(crate) op_type: OperationType,
43}
44
45impl OperationRef {
46    pub fn operation_name(&self) -> &str {
47        &self.name
48    }
49
50    pub fn variables(&self) -> &Value {
51        &self.variables
52    }
53
54    pub fn service(&self) -> &Arc<DataConnectService> {
55        &self.service
56    }
57}
58
59/// Strongly typed reference to a query operation.
60#[derive(Clone, Debug)]
61pub struct QueryRef(pub(crate) OperationRef);
62
63impl QueryRef {
64    pub fn operation_name(&self) -> &str {
65        self.0.operation_name()
66    }
67
68    pub fn variables(&self) -> &Value {
69        self.0.variables()
70    }
71
72    pub fn service(&self) -> &Arc<DataConnectService> {
73        self.0.service()
74    }
75}
76
77/// Strongly typed reference to a mutation operation.
78#[derive(Clone, Debug)]
79pub struct MutationRef(pub(crate) OperationRef);
80
81impl MutationRef {
82    pub fn operation_name(&self) -> &str {
83        self.0.operation_name()
84    }
85
86    pub fn variables(&self) -> &Value {
87        self.0.variables()
88    }
89
90    pub fn service(&self) -> &Arc<DataConnectService> {
91        self.0.service()
92    }
93}
94
95/// Minimal payload cached by the query manager.
96#[derive(Clone, Debug)]
97pub struct OpResult {
98    pub data: Value,
99    pub source: DataSource,
100    pub fetch_time: SystemTime,
101}
102
103/// Result returned from `execute_query`.
104#[derive(Clone, Debug)]
105pub struct QueryResult {
106    pub data: Value,
107    pub source: DataSource,
108    pub fetch_time: SystemTime,
109    pub query_ref: QueryRef,
110}
111
112impl QueryResult {
113    pub fn to_serialized(&self) -> SerializedQuerySnapshot {
114        SerializedQuerySnapshot {
115            data: self.data.clone(),
116            source: self.source,
117            fetch_time: system_time_to_string(self.fetch_time),
118            ref_info: RefInfo {
119                name: self.query_ref.operation_name().to_string(),
120                variables: self.query_ref.variables().clone(),
121                connector_config: self.query_ref.service().options().clone(),
122            },
123        }
124    }
125}
126
127/// Result returned from `execute_mutation`.
128#[derive(Clone, Debug)]
129pub struct MutationResult {
130    pub data: Value,
131    pub source: DataSource,
132    pub fetch_time: SystemTime,
133    pub mutation_ref: MutationRef,
134}
135
136/// Serializable reference snapshot (mirrors JS SDK `SerializedRef`).
137#[derive(Clone, Debug, Serialize, Deserialize)]
138pub struct SerializedQuerySnapshot {
139    pub data: Value,
140    pub source: DataSource,
141    pub fetch_time: String,
142    pub ref_info: RefInfo,
143}
144
145/// Serialized reference metadata.
146#[derive(Clone, Debug, Serialize, Deserialize)]
147pub struct RefInfo {
148    pub name: String,
149    pub variables: Value,
150    pub connector_config: DataConnectOptions,
151}
152
153pub(crate) fn system_time_to_string(time: SystemTime) -> String {
154    let datetime: DateTime<Utc> = time.into();
155    datetime.to_rfc3339()
156}
157
158pub(crate) fn string_to_system_time(value: &str) -> Option<SystemTime> {
159    DateTime::parse_from_rfc3339(value)
160        .or_else(|_| DateTime::parse_from_rfc2822(value))
161        .ok()
162        .map(SystemTime::from)
163}
164
165pub(crate) fn encode_query_key(name: &str, variables: &Value) -> String {
166    let payload = serde_json::json!({
167        "name": name,
168        "variables": variables,
169    });
170    serde_json::to_string(&payload).expect("query key serialization")
171}