diff --git a/easytier/Cargo.toml b/easytier/Cargo.toml index bb49807c..47ebe13a 100644 --- a/easytier/Cargo.toml +++ b/easytier/Cargo.toml @@ -51,7 +51,7 @@ toml = "0.8.12" chrono = { version = "0.4.37", features = ["serde"] } getset = "0.1.6" -optional_struct = "0.5.2" +optionize = "0.1" guarden = "0.1" diff --git a/easytier/src/common/config.rs b/easytier/src/common/config.rs index 0bf3a28f..370fbcd1 100644 --- a/easytier/src/common/config.rs +++ b/easytier/src/common/config.rs @@ -7,18 +7,18 @@ use crate::{ api::manage::ConfigSource as RpcConfigSource, common::{CompressionAlgoPb, PortForwardConfigPb, SecureModeConfig, SocketType}, }, - tunnel::{IpScheme, TunnelScheme, generate_digest_from_str}, + tunnel::{generate_digest_from_str, IpScheme, TunnelScheme}, utils, }; use anyhow::Context; -use base64::{Engine as _, prelude::BASE64_STANDARD}; +use base64::{prelude::BASE64_STANDARD, Engine as _}; use bon::Builder; -use clap::ValueEnum; use clap::builder::PossibleValue; +use clap::ValueEnum; use derivative::Derivative; use derive_more::{Constructor, Deref}; use getset::Getters; -use optional_struct::Applicable; +use optionize::Optionized; use serde::{Deserialize, Serialize}; use std::fmt::{Debug, Display}; use std::{ @@ -38,7 +38,7 @@ use tokio::io::AsyncReadExt as _; )] pub struct ConfigBase where - Raw: Applicable, + Raw: Optionized, ConfigBase: TryFrom, { #[deref] @@ -53,7 +53,7 @@ where impl Serialize for ConfigBase where - Raw: Applicable + Serialize, + Raw: Optionized + Serialize, ConfigBase: TryFrom, { fn serialize(&self, serializer: S) -> Result @@ -66,7 +66,7 @@ where impl Default for ConfigBase where - Raw: Applicable + Default, + Raw: Optionized + Default, ConfigBase: TryFrom, { fn default() -> Self { @@ -76,7 +76,7 @@ where impl ConfigBase where - Raw: Applicable, + Raw: Optionized, ConfigBase: TryFrom, { pub fn into_parsed(self) -> Parsed { @@ -93,7 +93,7 @@ where pub fn update(self, config: Raw) -> Result>::Error> { let mut raw = self.into_raw(); - config.apply_to_opt(&mut raw); + raw.merge(config); raw.try_into() } } diff --git a/easytier/src/dns/config/dns.rs b/easytier/src/dns/config/dns.rs index 5f129ecd..8c344d3c 100644 --- a/easytier/src/dns/config/dns.rs +++ b/easytier/src/dns/config/dns.rs @@ -5,19 +5,21 @@ use crate::dns::config::{DNS_DEFAULT_ADDRESSES, DNS_DEFAULT_DOMAIN}; use crate::dns::utils::addr::NameServerAddrGroup; use crate::proto::dns::GetExportConfigResponse; use hickory_proto::rr::LowerName; -use optional_struct::{Applicable, optional_struct}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; +use optionize::{optionized, Optionizable}; -#[optional_struct(DnsConfigRaw)] +#[optionized] +#[optionize(name = "DnsConfigRaw")] #[derive(Debug, Clone, Default, PartialEq, Deserialize, Serialize)] pub struct DnsConfigParsed { pub disabled: bool, #[serde(rename = "zone")] pub zones: Vec, - #[optional_skip_wrap] + #[optionize(flatten)] #[serde(flatten)] pub policies: HashMap, + #[optionize(flatten)] pub name: Option, pub domain: LowerName, pub addresses: NameServerAddrGroup, @@ -28,13 +30,12 @@ pub type DnsConfig = ConfigBase; impl From for DnsConfig { fn from(raw: DnsConfigRaw) -> Self { - let default = DnsConfigParsed { + let mut parsed = DnsConfigParsed { domain: DNS_DEFAULT_DOMAIN.clone(), addresses: DNS_DEFAULT_ADDRESSES.clone(), ..Default::default() }; - - let parsed = raw.clone().build(default); + parsed.load(raw.clone()); Self::new(parsed, raw, ()) } } diff --git a/easytier/src/dns/config/zone.rs b/easytier/src/dns/config/zone.rs index 7ed62a58..a254b3b1 100644 --- a/easytier/src/dns/config/zone.rs +++ b/easytier/src/dns/config/zone.rs @@ -7,11 +7,11 @@ use derive_more::From; use hickory_proto::op::ResponseCode; use hickory_proto::rr::LowerName; use maplit::hashset; -use optional_struct::{Applicable, optional_struct}; use serde::{Deserialize, Serialize}; use std::collections::HashSet; use std::convert::TryFrom; use std::net::{Ipv4Addr, Ipv6Addr}; +use optionize::{optionized, Optionizable}; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Hash, From, Deserialize, Serialize)] #[serde(untagged)] @@ -38,15 +38,16 @@ impl From for Fallthrough { } } -#[optional_struct(ZoneConfigRaw)] +#[optionized] +#[optionize(name = "ZoneConfigRaw")] #[derive(Debug, Clone, Default, PartialEq, Deserialize, Serialize)] pub struct ZoneConfigParsed { - #[optional_skip_wrap] + #[optionize(flatten)] pub origin: LowerName, pub ttl: u32, pub records: Vec, pub forwarders: NameServerAddrGroup, - #[optional_skip_wrap] + #[optionize(flatten)] #[serde(flatten)] pub policy: ZonePolicyConfig, pub fallthrough: HashSet, @@ -70,15 +71,13 @@ impl TryFrom for ZoneConfig { type Error = anyhow::Error; fn try_from(raw: ZoneConfigRaw) -> Result { - let default = ZoneConfigParsed { + let mut parsed = ZoneConfigParsed { fallthrough: hashset! {Fallthrough::Any}, ..Default::default() }; - - let parsed = raw.clone().build(default); + parsed.load(raw.clone()); let data = (&parsed).into(); let _ = Zone::try_from(&data)?; // validation - Ok(Self::new(parsed, raw, data)) } }