1use std::{
2 collections::{HashMap, HashSet},
3 future::Future,
4};
5
6use redis::{Cmd, ToRedisArgs};
7use serde::Deserialize;
8
9use crate::error::FCallResult;
10
11#[derive(Debug, Deserialize)]
15pub struct RedisArgs {
16 pub host: String,
18 pub port: usize,
20 pub db: usize,
22 pub username: Option<String>,
24 pub password: Option<String>,
26}
27
28impl RedisArgs {
29 pub fn to_client(self) -> FCallResult<redis::Client> {
31 let client =
32 redis::Client::open(format!("redis://{}:{}/{}", self.host, self.port, self.db))?;
33
34 if let Some(username) = self.username {
35 redis::cmd("AUTH")
36 .arg(username)
37 .arg(self.password.unwrap())
38 .exec(&mut client.get_connection()?)?;
39 }
40
41 Ok(client)
42 }
43}
44
45pub enum PluginData<'a> {
49 Hash {
50 title: &'a str,
51 items: HashMap<&'a str, &'a str>,
52 },
53 List {
54 title: &'a str,
55 items: Vec<(&'a str, &'a str, &'a str)>,
56 },
57 String {
58 title: &'a str,
59 content_type: StringContentType,
60 content: &'a str,
61 },
62 Table {
63 title: &'a str,
64 num_columns: usize,
65 rows: Vec<Vec<&'a str>>,
66 },
67}
68
69impl<'a> PluginData<'a> {
70 pub fn add_as_args(&'a self, cmd: &mut Cmd) {
73 match self {
74 PluginData::Hash { title, items } => {
75 cmd.arg("hash").arg(title);
76 for (key, val) in items {
77 cmd.arg(key).arg(val);
78 }
79 }
80 PluginData::List { title, items } => {
81 cmd.arg("list").arg(title).arg(items);
82 }
83 PluginData::String {
84 title,
85 content_type,
86 content,
87 } => {
88 cmd.arg("string").arg(title).arg(content_type).arg(content);
89 }
90 PluginData::Table {
91 title,
92 num_columns,
93 rows,
94 } => {
95 cmd.arg("table").arg(title).arg(num_columns);
96 for row in rows {
97 for col in row {
98 cmd.arg(col);
99 }
100 }
101 }
102 };
103 }
104}
105
106pub enum StringContentType {
108 HTML,
109 Markdown,
110 Plain,
111}
112
113impl ToRedisArgs for StringContentType {
114 fn write_redis_args<W>(&self, out: &mut W)
115 where
116 W: ?Sized + redis::RedisWrite,
117 {
118 match self {
119 StringContentType::HTML => out.write_arg("html".as_bytes()),
120 StringContentType::Markdown => out.write_arg("markdown".as_bytes()),
121 StringContentType::Plain => out.write_arg("plain".as_bytes()),
122 }
123 }
124}
125
126pub struct Node {
128 pub name: String,
129 pub link_id: String,
130 pub alt_names: HashSet<String>,
131 pub dns_names: HashSet<String>,
132 pub raw_ids: HashSet<String>,
133 pub plugins: HashSet<String>,
134}
135
136pub trait NetdoxReader {
140 fn get_default_network(&mut self) -> impl Future<Output = FCallResult<String>> + Send;
142 fn qualify_dns_names(
144 &mut self,
145 names: Vec<String>,
146 ) -> impl Future<Output = FCallResult<Vec<String>>> + Send;
147 fn get_dns_names(&mut self) -> impl Future<Output = FCallResult<HashSet<String>>> + Send;
149 fn get_nodes(&mut self) -> impl Future<Output = FCallResult<Vec<Node>>> + Send;
151 fn get_node(&mut self, link_id: &str) -> impl Future<Output = FCallResult<Node>> + Send;
153 fn get_dns_metadata(
155 &mut self,
156 name: &str,
157 ) -> impl Future<Output = FCallResult<HashMap<String, String>>> + Send;
158 fn get_node_metadata(
160 &mut self,
161 node: &Node,
162 ) -> impl Future<Output = FCallResult<HashMap<String, String>>> + Send;
163}
164
165pub trait NetdoxWriter {
167 fn put_dns(
169 &mut self,
170 plugin: &str,
171 name: &str,
172 rtype: Option<&str>,
173 value: Option<&str>,
174 ) -> impl Future<Output = FCallResult<()>> + Send;
175
176 fn put_dns_plugin_data<'a>(
178 &mut self,
179 plugin: &str,
180 name: &str,
181 pdata_id: &str,
182 data: PluginData<'a>,
183 ) -> impl Future<Output = FCallResult<()>> + Send;
184
185 fn put_dns_metadata(
187 &mut self,
188 plugin: &str,
189 name: &str,
190 metadata: &HashMap<&str, &str>,
191 ) -> impl Future<Output = FCallResult<()>> + Send;
192
193 fn put_node(
195 &mut self,
196 plugin: &str,
197 name: &str,
198 dns_names: Vec<&str>,
199 exclusive: bool,
200 link_id: Option<&str>,
201 ) -> impl Future<Output = FCallResult<()>> + Send;
202
203 fn put_node_plugin_data<'a>(
205 &mut self,
206 plugin: &str,
207 dns_names: Vec<&str>,
208 pdata_id: &str,
209 data: PluginData<'a>,
210 ) -> impl Future<Output = FCallResult<()>> + Send;
211
212 fn put_proc_node_plugin_data<'a>(
214 &mut self,
215 plugin: &str,
216 link_id: &str,
217 pdata_id: &str,
218 data: PluginData<'a>,
219 ) -> impl Future<Output = FCallResult<()>> + Send;
220
221 fn put_node_metadata(
223 &mut self,
224 plugin: &str,
225 dns_names: Vec<&str>,
226 metadata: &HashMap<&str, &str>,
227 ) -> impl Future<Output = FCallResult<()>> + Send;
228
229 fn put_proc_node_metadata(
231 &mut self,
232 plugin: &str,
233 link_id: &str,
234 metadata: &HashMap<&str, &str>,
235 ) -> impl Future<Output = FCallResult<()>> + Send;
236
237 fn put_report(
239 &mut self,
240 plugin: &str,
241 report_id: &str,
242 title: &str,
243 length: usize,
244 ) -> impl Future<Output = FCallResult<()>> + Send;
245
246 fn put_report_data<'a>(
248 &mut self,
249 plugin: &str,
250 report_id: &str,
251 index: usize,
252 data: PluginData<'a>,
253 ) -> impl Future<Output = FCallResult<()>> + Send;
254}