1use napi::bindgen_prelude::*;
5use napi_derive::napi;
6use redis::AsyncCommands;
7use redis_swapplex::get_connection;
8use serde_json::Value;
9
10#[napi]
11pub async fn get(key: String) -> Result<Option<Value>> {
13 let mut conn = get_connection();
14
15 let bytes: Option<Vec<u8>> = conn
16 .get(key)
17 .await
18 .map_err(|err| Error::new(Status::GenericFailure, format!("{:?}", err)))?;
19
20 if let Some(mut bytes) = bytes {
21 let value: Value = simd_json::serde::from_slice(bytes.as_mut_slice())
22 .map_err(|err| Error::new(Status::GenericFailure, err.to_string()))?;
23
24 Ok(Some(value))
25 } else {
26 Ok(None)
27 }
28}
29
30#[napi]
31pub async fn mget(keys: Vec<String>) -> Result<Vec<Option<Value>>> {
33 let mut conn = get_connection();
34
35 let data: Vec<Option<Vec<u8>>> = redis::cmd("MGET")
36 .arg(&keys)
37 .query_async(&mut conn)
38 .await
39 .map_err(|err| Error::new(Status::GenericFailure, format!("{:?}", err)))?;
40
41 data
42 .into_iter()
43 .map(|bytes| {
44 if let Some(mut bytes) = bytes {
45 let value = simd_json::serde::from_slice(bytes.as_mut_slice())
46 .map_err(|err| Error::new(Status::GenericFailure, err.to_string()))?;
47
48 Ok(Some(value))
49 } else {
50 Ok(None)
51 }
52 })
53 .collect::<Result<Vec<Option<Value>>>>()
54}
55
56#[napi]
57pub async fn set(key: String, value: Option<Value>) -> Result<()> {
59 let value = match value {
60 Some(value) => Some(
61 simd_json::to_vec(&value)
62 .map_err(|err| Error::new(Status::GenericFailure, err.to_string()))?,
63 ),
64 None => None,
65 };
66
67 let mut conn = get_connection();
68
69 let _: () = conn
70 .set(key, value)
71 .await
72 .map_err(|err| Error::new(Status::GenericFailure, format!("{:?}", err)))?;
73
74 Ok(())
75}
76
77#[napi]
78pub async fn compare_and_swap(key: String, current: Value, value: Option<Value>) -> Result<i64> {
80 let current = simd_json::to_vec(¤t)
81 .map_err(|err| Error::new(Status::GenericFailure, err.to_string()))?;
82
83 let value = match value {
84 Some(value) => simd_json::to_vec(&value)
85 .map_err(|err| Error::new(Status::GenericFailure, err.to_string()))?,
86
87 None => vec![],
88 };
89
90 let mut conn = get_connection();
91
92 let n_modified: i64 = redis::cmd("CAS")
93 .arg(&[key.as_bytes(), ¤t, &value])
94 .query_async(&mut conn)
95 .await
96 .map_err(|err| Error::new(Status::GenericFailure, format!("{:?}", err)))?;
97
98 Ok(n_modified)
99}
100
101#[napi]
102pub async fn mset(data: Vec<(String, Option<Value>)>) -> Result<()> {
104 let data = data
105 .into_iter()
106 .map(|(key, value)| match value {
107 Some(value) => {
108 let bytes: Vec<u8> = simd_json::to_vec(&value)
109 .map_err(|err| Error::new(Status::GenericFailure, err.to_string()))?;
110
111 Ok((key, Some(bytes)))
112 }
113 None => Ok((key, None)),
114 })
115 .collect::<Result<Vec<(String, Option<Vec<u8>>)>>>()?;
116
117 let mut conn = get_connection();
118
119 let _: () = redis::cmd("MSET")
120 .arg(&data[..])
121 .query_async(&mut conn)
122 .await
123 .map_err(|err| Error::new(Status::GenericFailure, format!("{:?}", err)))?;
124
125 Ok(())
126}