rd_interface/
context.rs

1use crate::Value;
2use serde::{de::DeserializeOwned, Serialize};
3use std::{collections::HashMap, fmt::Debug, net::SocketAddr};
4use thiserror::Error;
5
6/// Context error
7#[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
16/// Defines common used field with its key and type
17pub trait CommonField: DeserializeOwned + Serialize + 'static {
18    const KEY: &'static str;
19}
20
21/// A context stores a source endpoint, a process info and other any values
22/// during connecting.
23#[derive(Debug, Clone)]
24pub struct Context {
25    data: HashMap<String, Value>,
26    composite_list: Vec<String>,
27}
28
29impl Context {
30    /// new a empty context
31    pub fn new() -> Context {
32        Context {
33            data: HashMap::new(),
34            composite_list: Vec::new(),
35        }
36    }
37    /// new a context from socket addr
38    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    /// Inserts a key-value pair into the context.
45    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    /// Removes a key from the context
50    pub fn remove<T: DeserializeOwned>(&mut self, key: &str) -> Result<()> {
51        self.data.remove(key).ok_or(Error::NonExist)?;
52        Ok(())
53    }
54    /// Returns a value corresponding to the key.
55    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    /// Inserts a key-value pair into the context.
60    pub fn insert_value(&mut self, key: String, value: Value) {
61        self.data.insert(key, value);
62    }
63    /// Removes a key from the context, returning the value at the key if the key was previously in the context.
64    pub fn remove_value(&mut self, key: &str) -> Result<()> {
65        self.data.remove(key);
66        Ok(())
67    }
68    /// Returns a value corresponding to the key.
69    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    /// Inserts a key-value pair into the context.
76    pub fn insert_common<T: CommonField>(&mut self, value: T) -> Result<()> {
77        self.insert(T::KEY.to_string(), value)
78    }
79    /// Returns a value corresponding to the key.
80    pub fn get_common<T: CommonField>(&self) -> Result<T> {
81        self.get(T::KEY)
82    }
83    /// Add composite to composite_list
84    pub fn append_composite(&mut self, composite_name: impl Into<String>) {
85        self.composite_list.push(composite_name.into())
86    }
87    /// Get composite_list
88    pub fn composite_list(&self) -> &Vec<String> {
89        &self.composite_list
90    }
91}
92
93/// Common context keys and types
94pub 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}