singbox_config/def/
dns.rs

1use serde::{Serialize, Deserialize};
2
3use super::{rules, types::OneOrMany};
4
5
6#[derive(Debug, Serialize, Deserialize, Default)]
7pub struct Dns {
8    pub rules: Vec<Rule>,
9    pub servers: Vec<Server>,
10    #[serde(rename="final")]
11    #[serde(skip_serializing_if = "Option::is_none")]
12    pub default: Option<String>,
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub strategy: Option<String>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub disable_cache: Option<bool>,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub disable_expire: Option<bool>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub independent_cache: Option<bool>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub reverse_mapping: Option<bool>,
23}
24
25#[derive(Debug, Serialize, Deserialize, Default)]
26pub struct Rule {
27    pub server: String,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub outbound: Option<OneOrMany<String>>,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub network: Option<String>,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub disable_cache: Option<bool>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub rewrite_ttl: Option<u32>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub query_type: Option<OneOrMany<String>>,
38    #[serde(flatten)]
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub rule: Option<rules::Rule>,
41}
42
43#[derive(Debug, Serialize, Deserialize, Default)]
44pub struct Server {
45    pub tag: String,
46    pub address: String,
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub address_resolver: Option<String>,
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub address_strategy: Option<String>,
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub strategy: Option<String>,
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub detour: Option<String>,
55}
56
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn dns_ser() {
64        let str = r#"
65        {
66          "rules": [
67            {
68              "disable_cache": true,
69              "geosite": "category-ads-all",
70              "server": "block"
71            },
72            {
73              "geosite": ["cn", "private"],
74              "inbound": "tun-in",
75              "server": "local"
76            }
77          ],
78          "servers": [
79            {
80              "address": "192.168.1.1",
81              "detour": "direct",
82              "tag": "local"
83            },
84            {
85              "address": "rcode://success",
86              "tag": "block"
87            }
88          ],
89          "strategy": "prefer_ipv4"
90        }
91        "#;
92        let dns: Dns = serde_json::from_str(&str).unwrap();
93        let reser = serde_json::to_string(&dns).unwrap();
94        println!("reserialized dns = {reser}");
95    }
96}