featherbit/plugins/native/
store_delete.rs1use async_trait::async_trait;
9use std::collections::HashMap;
10use std::sync::Arc;
11
12use crate::context::Context;
13use crate::plugins::resources::PluginResources;
14use crate::plugins::util::store_kv::{self, StoreHandle};
15use crate::plugins::{Plugin, PluginResult};
16use crate::vars::template::Template;
17
18#[cfg(feature = "redis-store")]
19use crate::plugins::PluginOutput;
20
21#[derive(Debug)]
22pub struct StoreDeletePlugin {
23 store: StoreHandle,
24 key: Template,
25}
26
27impl StoreDeletePlugin {
28 pub fn from_config(
32 config: &HashMap<String, serde_json::Value>,
33 resources: &Arc<PluginResources>,
34 ) -> Result<Self, String> {
35 let key = store_kv::required_template(config, "key", "store-delete")?;
36 Ok(Self {
37 store: store_kv::resolve(config, resources, "store-delete")?,
38 key,
39 })
40 }
41}
42
43#[async_trait]
44impl Plugin for StoreDeletePlugin {
45 fn plugin_type(&self) -> &str {
46 "store-delete"
47 }
48
49 fn reads_response_body(&self) -> bool {
50 self.key.references_response_body()
51 }
52
53 #[cfg(feature = "redis-store")]
54 async fn execute(&self, ctx: Context) -> PluginResult {
55 use redis::AsyncCommands;
56
57 let rendered = self.key.render(&ctx).to_string();
58 if rendered.is_empty() {
59 return Err(store_kv::key_invalid(
60 ctx,
61 "store-delete",
62 "DEL",
63 &self.store.name,
64 ));
65 }
66 let key = self.store.key_for(&rendered);
67
68 let mut conn = match self.store.conn().await {
69 Ok(c) => c,
70 Err(e) => {
71 return Err(store_kv::store_error(
72 ctx,
73 "store-delete",
74 "DEL",
75 &self.store.name,
76 e,
77 ))
78 }
79 };
80
81 match conn.del::<_, u64>(&key).await {
83 Ok(_) => Ok(PluginOutput::success(ctx)),
84 Err(e) => Err(store_kv::store_error(
85 ctx,
86 "store-delete",
87 "DEL",
88 &self.store.name,
89 e.to_string(),
90 )),
91 }
92 }
93
94 #[cfg(not(feature = "redis-store"))]
95 async fn execute(&self, ctx: Context) -> PluginResult {
96 Err(store_kv::store_error(
97 ctx,
98 "store-delete",
99 "DEL",
100 &self.store.name,
101 "built without the redis-store feature".to_string(),
102 ))
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109 use crate::plugins::resources::PluginResources;
110 use std::collections::HashMap;
111
112 fn cfg(json: serde_json::Value) -> HashMap<String, serde_json::Value> {
113 serde_json::from_value(json).unwrap()
114 }
115
116 #[test]
117 fn test_requires_a_key() {
118 let r = PluginResources::empty();
119 let err = StoreDeletePlugin::from_config(&cfg(serde_json::json!({ "store": "s" })), &r)
120 .unwrap_err();
121 assert!(err.contains("key"), "{err}");
122 }
123}