safir_core/
mem.rs

1use anyhow::Result;
2
3use async_trait::async_trait;
4
5use crate::config::SafirConfig;
6use crate::utils::{self, confirm_entry, print_headless};
7use crate::SafirEngine;
8use rubin::net::client::RubinClient;
9
10fn safir_offline() {
11    eprintln!(
12        "Safir Memcache does not appear to be online.\nStart it by running `safir-mem start`."
13    );
14}
15
16pub struct SafirMemcache {
17    is_online: bool,
18    client: RubinClient,
19}
20
21impl SafirMemcache {
22    pub async fn new(cfg: &SafirConfig) -> Result<Self> {
23        Ok(Self {
24            is_online: utils::is_safir_running(cfg.memcache_pid),
25            client: RubinClient::new("127.0.0.1", 9876),
26        })
27    }
28
29    pub async fn dump_store(&self, path: &str) -> Result<()> {
30        if !self.is_online {
31            safir_offline();
32            return Ok(());
33        }
34
35        self.client.dump_store(path).await?;
36        println!("Safir memcache dumped to {}", path);
37
38        Ok(())
39    }
40}
41
42#[async_trait]
43impl SafirEngine for SafirMemcache {
44    async fn add_entry(&mut self, key: String, value: String) -> Result<()> {
45        if !self.is_online {
46            safir_offline();
47            return Ok(());
48        }
49
50        self.client.insert_string(&key, &value).await?;
51        Ok(())
52    }
53
54    async fn get_entry(&self, key: String) -> Result<()> {
55        if !self.is_online {
56            safir_offline();
57            return Ok(());
58        }
59
60        let value = if let Ok(val) = self.client.get_string(&key).await {
61            val
62        } else {
63            String::from("")
64        };
65
66        print_headless("", &key, &value);
67
68        Ok(())
69    }
70
71    async fn remove_entry(&mut self, keys: Vec<String>) -> Result<()> {
72        if !self.is_online {
73            safir_offline();
74            return Ok(());
75        }
76
77        for key in &keys {
78            self.client.remove_string(key).await?;
79        }
80
81        Ok(())
82    }
83
84    async fn set_commands(&mut self, prefix: &str, keys: &Vec<String>) {
85        if !self.is_online {
86            safir_offline();
87            return;
88        }
89
90        for key in keys {
91            if let Ok(value) = self.client.get_string(key).await {
92                print_headless(prefix, key, &value);
93            }
94        }
95    }
96
97    async fn clear_entries(&mut self) -> Result<()> {
98        if !self.is_online {
99            safir_offline();
100            return Ok(());
101        }
102
103        if confirm_entry("Are you sure you want to clear the store?") {
104            self.client.clear_strings().await?;
105        }
106
107        Ok(())
108    }
109
110    fn to_type(&self) -> &dyn std::any::Any {
111        self
112    }
113}