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#[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}