rabbit_digger/
config.rs

1pub mod default;
2
3use std::{collections::HashMap, path::PathBuf};
4
5use anyhow::Result;
6use rd_interface::Value;
7use serde_derive::{Deserialize, Serialize};
8use serde_with::{serde_as, OneOrMany};
9
10pub type ConfigNet = HashMap<String, Net>;
11pub type ConfigServer = HashMap<String, Server>;
12pub type ConfigComposite = HashMap<String, CompositeName>;
13
14#[derive(Debug)]
15pub enum AllNet {
16    Net(Net),
17    Composite(CompositeName),
18    Root(Vec<String>),
19}
20
21impl AllNet {
22    pub fn get_dependency(&self) -> Vec<&String> {
23        match self {
24            AllNet::Net(Net { chain, .. }) => chain.iter().collect(),
25            AllNet::Composite(CompositeName {
26                composite,
27                net_list,
28                ..
29            }) => match &composite.0 {
30                Composite::Rule(CompositeRule { rule }) => rule.iter().map(|i| &i.target).collect(),
31                Composite::Select => net_list.iter().collect(),
32            },
33            AllNet::Root(v) => v.iter().collect(),
34        }
35    }
36}
37
38#[derive(Debug, Serialize, Deserialize, Clone, Default)]
39pub struct Config {
40    #[serde(default)]
41    pub id: String,
42    #[serde(default = "default::plugins")]
43    pub plugin_path: PathBuf,
44    #[serde(default)]
45    pub net: ConfigNet,
46    #[serde(default)]
47    pub server: ConfigServer,
48    #[serde(default)]
49    pub composite: ConfigComposite,
50    #[serde(default)]
51    pub import: Vec<Import>,
52}
53
54#[derive(Debug, Serialize, Deserialize, Clone)]
55pub struct Import {
56    pub name: Option<String>,
57    #[serde(rename = "type")]
58    pub format: String,
59    pub path: PathBuf,
60    #[serde(flatten)]
61    pub opt: Value,
62}
63
64/// Define a net composited from many other net
65#[derive(Debug, Serialize, Deserialize, Clone)]
66pub struct CompositeName {
67    pub name: Option<String>,
68    #[serde(default)]
69    pub net_list: Vec<String>,
70    #[serde(flatten)]
71    pub composite: CompositeDefaultType,
72}
73
74#[derive(Debug, Serialize, Deserialize, Clone)]
75#[serde(tag = "type", rename_all = "lowercase")]
76pub enum Composite {
77    Rule(CompositeRule),
78    Select,
79}
80
81impl Into<CompositeDefaultType> for Composite {
82    fn into(self) -> CompositeDefaultType {
83        CompositeDefaultType(self)
84    }
85}
86
87#[derive(Debug, Serialize, Clone)]
88pub struct CompositeDefaultType(pub Composite);
89
90impl<'de> serde::Deserialize<'de> for CompositeDefaultType {
91    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
92    where
93        D: serde::Deserializer<'de>,
94    {
95        use serde::de;
96
97        let v = Value::deserialize(deserializer)?;
98        match Option::<String>::deserialize(&v["type"]).map_err(de::Error::custom)? {
99            Some(_) => {
100                let inner = Composite::deserialize(v).map_err(de::Error::custom)?;
101                Ok(CompositeDefaultType(inner))
102            }
103            None => {
104                let inner = CompositeRule::deserialize(v).map_err(de::Error::custom)?;
105                Ok(CompositeDefaultType(Composite::Rule(inner)))
106            }
107        }
108    }
109}
110
111#[derive(Debug, Serialize, Deserialize, Clone)]
112#[serde(untagged)]
113pub enum Chain {
114    One(String),
115    Many(Vec<String>),
116}
117
118impl Chain {
119    pub fn into_vec(self) -> Vec<String> {
120        match self {
121            Chain::One(s) => vec![s],
122            Chain::Many(v) => v,
123        }
124    }
125    pub fn to_vec(&self) -> Vec<String> {
126        match self {
127            Chain::One(s) => vec![s.clone()],
128            Chain::Many(v) => v.clone(),
129        }
130    }
131    pub fn as_ref(&self) -> Vec<&str> {
132        match self {
133            Chain::One(s) => vec![&s],
134            Chain::Many(v) => v.iter().map(AsRef::as_ref).collect(),
135        }
136    }
137}
138
139#[serde_as]
140#[derive(Debug, Serialize, Deserialize, Clone)]
141pub struct Net {
142    #[serde(rename = "type")]
143    pub net_type: String,
144    #[serde_as(deserialize_as = "OneOrMany<_>")]
145    #[serde(default = "default::local_chain")]
146    pub chain: Vec<String>,
147    #[serde(flatten)]
148    pub opt: Value,
149}
150
151#[derive(Debug, Serialize, Deserialize, Clone)]
152pub struct Server {
153    #[serde(rename = "type")]
154    pub server_type: String,
155    #[serde(default = "default::local_string")]
156    pub listen: String,
157    #[serde(default = "default::rule")]
158    pub net: String,
159    #[serde(flatten)]
160    pub opt: Value,
161}
162
163#[derive(Debug, Serialize, Deserialize, Clone)]
164pub struct CompositeRuleItem {
165    pub target: String,
166    #[serde(flatten)]
167    pub matcher: Matcher,
168}
169
170#[derive(Debug, Serialize, Deserialize, Clone)]
171pub struct CompositeRule {
172    pub rule: Vec<CompositeRuleItem>,
173}
174
175#[derive(Debug, Serialize, Deserialize, Clone)]
176#[serde(tag = "type", rename_all = "lowercase")]
177pub enum Matcher {
178    Domain { method: String, domain: String },
179    IpCidr { ip_cidr: String },
180    Any,
181}
182
183impl Config {
184    pub fn merge(&mut self, other: Config) {
185        self.plugin_path = other.plugin_path;
186        self.net.extend(other.net);
187        self.server.extend(other.server);
188        self.composite.extend(other.composite);
189        self.import.extend(other.import);
190    }
191}