Skip to main content

hinge_rs/client/
persistence.rs

1use super::HingeClient;
2use crate::errors::HingeError;
3use crate::storage::Storage;
4use serde_json::json;
5use std::path::PathBuf;
6
7impl<S: Storage + Clone> HingeClient<S> {
8    pub fn save_session(&self, path: &str) -> Result<(), HingeError> {
9        let session = json!({
10          "phoneNumber": self.phone_number,
11          "deviceId": self.device_id,
12          "installId": self.install_id,
13          "sessionId": self.session_id,
14          "installed": self.installed,
15          "hingeAuth": self.hinge_auth,
16          "sendbirdAuth": self.sendbird_auth,
17          "sendbirdSessionKey": self.sendbird_session_key,
18        });
19        let data =
20            serde_json::to_string_pretty(&session).map_err(|e| HingeError::Serde(e.to_string()))?;
21        self.storage
22            .write_string(path, &data)
23            .map_err(|e| HingeError::Storage(e.to_string()))?;
24        Ok(())
25    }
26
27    pub fn load_session(&mut self, path: &str) -> Result<(), HingeError> {
28        if !self.storage.exists(path) {
29            return Ok(());
30        }
31
32        let data = self
33            .storage
34            .read_to_string(path)
35            .map_err(|e| HingeError::Storage(e.to_string()))?;
36        let v: serde_json::Value =
37            serde_json::from_str(&data).map_err(|e| HingeError::Serde(e.to_string()))?;
38
39        if let Some(s) = v.get("phoneNumber").and_then(|v| v.as_str()) {
40            self.phone_number = s.to_string();
41        }
42        if let Some(s) = v.get("deviceId").and_then(|v| v.as_str()) {
43            self.device_id = s.to_string();
44        }
45        if let Some(s) = v.get("installId").and_then(|v| v.as_str()) {
46            self.install_id = s.to_string();
47        }
48        if let Some(s) = v.get("sessionId").and_then(|v| v.as_str()) {
49            self.session_id = s.to_string();
50        }
51        if let Some(b) = v.get("installed").and_then(|v| v.as_bool()) {
52            self.installed = b;
53        }
54        if let Some(t) = v.get("hingeAuth").cloned() {
55            self.hinge_auth = serde_json::from_value(t).ok();
56        }
57        if let Some(t) = v.get("sendbirdAuth").cloned() {
58            self.sendbird_auth = serde_json::from_value(t).ok();
59        }
60        if let Some(k) = v.get("sendbirdSessionKey").and_then(|v| v.as_str()) {
61            self.sendbird_session_key = Some(k.to_string());
62        }
63        Ok(())
64    }
65
66    pub fn load_tokens_secure(&mut self) -> Result<(), HingeError> {
67        if let Some(store) = &self.secret_store {
68            if let Some(v) = store
69                .get_secret("hinge_auth")
70                .map_err(|e| HingeError::Storage(e.to_string()))?
71            {
72                self.hinge_auth = serde_json::from_str(&v).ok();
73            }
74            if let Some(v) = store
75                .get_secret("sendbird_auth")
76                .map_err(|e| HingeError::Storage(e.to_string()))?
77            {
78                self.sendbird_auth = serde_json::from_str(&v).ok();
79            }
80        }
81        Ok(())
82    }
83
84    pub fn with_persistence(
85        mut self,
86        session_path: Option<String>,
87        cache_dir: Option<PathBuf>,
88        auto_persist: bool,
89    ) -> Self {
90        self.session_path = session_path;
91        self.cache_dir = cache_dir;
92        self.auto_persist = auto_persist;
93
94        if let Some(path) = self.session_path.clone() {
95            let _ = self.load_session(&path);
96        }
97        if let Some(dir) = &self.cache_dir {
98            let rec_path = dir.join(format!("recommendations_{}.json", self.session_id));
99            let _ = self.load_recommendations(rec_path.to_string_lossy().as_ref());
100        }
101        self
102    }
103
104    pub(super) fn recs_cache_path(&self) -> Option<String> {
105        self.cache_dir.as_ref().map(|d| {
106            d.join(format!("recommendations_{}.json", self.session_id))
107                .to_string_lossy()
108                .into_owned()
109        })
110    }
111
112    pub(super) fn prompts_cache_path(&self) -> Option<String> {
113        self.cache_dir
114            .as_ref()
115            .map(|d| d.join("prompts_cache.json").to_string_lossy().into_owned())
116    }
117}