1use crate::Value;
2use serde::{de::DeserializeOwned, Serialize};
3use std::{collections::HashMap, fmt::Debug, net::SocketAddr};
4use thiserror::Error;
5
6#[derive(Debug, Error)]
8pub enum Error {
9 #[error("serde error {0}")]
10 Serde(#[from] serde_json::Error),
11 #[error("item not exists")]
12 NonExist,
13}
14pub type Result<T, E = Error> = std::result::Result<T, E>;
15
16pub trait CommonField: DeserializeOwned + Serialize + 'static {
18 const KEY: &'static str;
19}
20
21#[derive(Debug, Clone)]
24pub struct Context {
25 data: HashMap<String, Value>,
26 composite_list: Vec<String>,
27}
28
29impl Context {
30 pub fn new() -> Context {
32 Context {
33 data: HashMap::new(),
34 composite_list: Vec::new(),
35 }
36 }
37 pub fn from_socketaddr(addr: SocketAddr) -> Context {
39 let mut ctx = Context::new();
40 ctx.insert_common(common_field::SourceAddress { addr })
41 .unwrap();
42 ctx
43 }
44 pub fn insert<I: Serialize>(&mut self, key: String, value: I) -> Result<()> {
46 self.data.insert(key, serde_json::to_value(value)?);
47 Ok(())
48 }
49 pub fn remove<T: DeserializeOwned>(&mut self, key: &str) -> Result<()> {
51 self.data.remove(key).ok_or(Error::NonExist)?;
52 Ok(())
53 }
54 pub fn get<T: DeserializeOwned>(&self, key: &str) -> Result<T> {
56 let value = self.data.get(key).ok_or(Error::NonExist)?;
57 Ok(serde_json::from_value(value.clone())?)
58 }
59 pub fn insert_value(&mut self, key: String, value: Value) {
61 self.data.insert(key, value);
62 }
63 pub fn remove_value(&mut self, key: &str) -> Result<()> {
65 self.data.remove(key);
66 Ok(())
67 }
68 pub fn get_value(&self, key: &str) -> Result<Value> {
70 match self.data.get(key) {
71 Some(v) => Ok(v.to_owned()),
72 None => Err(Error::NonExist),
73 }
74 }
75 pub fn insert_common<T: CommonField>(&mut self, value: T) -> Result<()> {
77 self.insert(T::KEY.to_string(), value)
78 }
79 pub fn get_common<T: CommonField>(&self) -> Result<T> {
81 self.get(T::KEY)
82 }
83 pub fn append_composite(&mut self, composite_name: impl Into<String>) {
85 self.composite_list.push(composite_name.into())
86 }
87 pub fn composite_list(&self) -> &Vec<String> {
89 &self.composite_list
90 }
91}
92
93pub mod common_field {
95 use super::CommonField;
96 use serde_derive::{Deserialize, Serialize};
97
98 #[derive(Debug, Deserialize, Serialize)]
99 pub struct SourceAddress {
100 pub addr: std::net::SocketAddr,
101 }
102
103 impl CommonField for SourceAddress {
104 const KEY: &'static str = "source_address";
105 }
106
107 #[derive(Debug, Deserialize, Serialize)]
108 pub struct ProcessInfo {
109 pub process_name: String,
110 }
111
112 impl CommonField for ProcessInfo {
113 const KEY: &'static str = "process_info";
114 }
115}