pdk_data_storage_lib/distributed/
model.rs1use pdk_core::logger;
11
12use base64::{DecodeError, Engine};
13use std::collections::HashMap;
14use std::convert::TryFrom;
15
16use serde::{Deserialize, Serialize};
17
18const MAX_TTL_SECONDS: u32 = 2592000;
20
21#[derive(PartialEq, Eq, Debug)]
22pub enum StoreMode {
23 Always,
25 Absent,
27 Cas(String),
29}
30
31#[allow(dead_code)]
32#[doc(hidden)]
33#[derive(Deserialize, Debug)]
35pub struct Keys {
36 pub values: Vec<Key>,
37 next_page_token: Option<String>,
38}
39
40#[allow(dead_code)]
41#[doc(hidden)]
42#[derive(Deserialize, Debug)]
44pub struct Key {
45 #[serde(rename = "keyId")]
46 pub key_id: String,
47}
48
49#[allow(dead_code)]
50#[doc(hidden)]
51#[derive(Deserialize, Debug)]
53pub struct Partitions {
54 pub values: Vec<String>,
55 next_page_token: Option<String>,
56}
57
58#[allow(dead_code)]
59#[doc(hidden)]
60#[derive(Deserialize, Debug)]
62pub struct Stores {
63 pub values: Vec<Store>,
64 next_page_token: Option<String>,
65}
66
67#[derive(Serialize, Deserialize, Debug)]
68pub struct Store {
69 #[serde(rename = "storeId")]
70 store_id: String,
71
72 #[serde(rename = "defaultTtlSeconds")]
73 default_ttl_seconds: u32,
74
75 #[serde(rename = "maximumEntries")]
76 #[serde(skip_serializing_if = "Option::is_none")]
77 max_entries: Option<u32>,
78}
79
80#[allow(dead_code)]
81impl Store {
82 pub fn new(store_id: String, ttl_millis: Option<u32>, max_entries: Option<u32>) -> Self {
83 Self {
84 store_id,
85 default_ttl_seconds: convert_to_seconds(ttl_millis),
86 max_entries,
87 }
88 }
89
90 pub fn store_id(&self) -> &str {
91 self.store_id.as_str()
92 }
93
94 pub fn default_ttl_seconds(&self) -> u32 {
95 self.default_ttl_seconds
96 }
97
98 pub fn max_entries(&self) -> Option<u32> {
99 self.max_entries
100 }
101}
102
103#[derive(Serialize, Deserialize, Debug, PartialEq)]
104#[serde(rename_all = "UPPERCASE")]
105enum Types {
106 Number,
107 Binary,
108 String,
109}
110
111#[derive(Serialize, Deserialize, Debug)]
112#[doc(hidden)]
113pub struct Object {
114 #[serde(rename = "keyId", skip_serializing_if = "Option::is_none")]
115 key_id: Option<String>,
116
117 #[serde(skip_serializing_if = "Option::is_none")]
118 index: Option<u32>,
119
120 #[serde(skip_serializing_if = "Option::is_none")]
121 metadata: Option<HashMap<String, String>>,
122
123 #[serde(rename = "valueType")]
124 value_type: Types,
125
126 #[serde(rename = "stringValue", skip_serializing_if = "Option::is_none")]
127 string_value: Option<String>,
128
129 #[serde(rename = "numberValue", skip_serializing_if = "Option::is_none")]
130 number_value: Option<u64>,
131
132 #[serde(rename = "binaryValue", skip_serializing_if = "Option::is_none")]
133 binary_value: Option<String>,
134}
135
136impl TryFrom<&[u8]> for Object {
137 type Error = serde_json::Error;
138
139 fn try_from(value: &[u8]) -> serde_json::Result<Self> {
141 serde_json::from_slice(value)
142 }
143}
144
145impl Object {
146 pub fn new_binary(value: &[u8]) -> Self {
147 let result = base64::engine::general_purpose::STANDARD.encode(value);
148
149 Self {
150 key_id: None,
151 index: None,
152 metadata: None,
153 value_type: Types::Binary,
154 string_value: None,
155 number_value: None,
156 binary_value: Some(result),
157 }
158 }
159
160 pub fn get_binary(&self) -> Result<Vec<u8>, DecodeError> {
161 self.binary_value
162 .as_ref()
163 .map(|binary| base64::engine::general_purpose::STANDARD.decode(binary))
164 .unwrap_or(Ok(vec![]))
165 }
166}
167
168fn convert_to_seconds(ttl_millis: Option<u32>) -> u32 {
171 let mut ttl_seconds = ttl_millis.map_or(MAX_TTL_SECONDS, |m| m / 1000);
173
174 if ttl_seconds > MAX_TTL_SECONDS {
176 logger::warn!("TTL is greater than the maximum allowed value of {MAX_TTL_SECONDS} seconds. Setting TTL to default max value: {MAX_TTL_SECONDS} seconds.");
177 ttl_seconds = MAX_TTL_SECONDS;
178 }
179
180 ttl_seconds
181}
182
183#[cfg(test)]
184mod tests {
185 use super::{convert_to_seconds, MAX_TTL_SECONDS};
186
187 #[test]
188 fn test_convert_to_seconds_normal_ttl_millis() {
189 let result = convert_to_seconds(Some(60000));
190 assert_eq!(result, 60);
191 }
192
193 #[test]
194 fn test_convert_to_seconds_large_ttl_sets_max_ttl_value() {
195 let large_ttl_millis = (MAX_TTL_SECONDS + 1) * 1000;
196 let result = convert_to_seconds(Some(large_ttl_millis));
197 assert_eq!(result, MAX_TTL_SECONDS);
198 }
199
200 #[test]
201 fn test_convert_to_seconds_none_sets_max_ttl_value() {
202 let result = convert_to_seconds(None);
203 assert_eq!(result, MAX_TTL_SECONDS);
204 }
205}