From dd1483cb6d9c060a17dc68357975de2b1ec09c08 Mon Sep 17 00:00:00 2001 From: Gus Power Date: Wed, 14 May 2025 13:21:08 +0100 Subject: reduce size of DnsRecordType (introduce enum), add overall config w/ supporting "full" test file. --- src/config.rs | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/config.rs (limited to 'src/config.rs') diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..9230f38 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,115 @@ +use crate::dyndns_service::DynDnsProvider; +use fqdn::FQDN; +use serde::{Deserialize, Serialize}; +use serde_with::DisplayFromStr; +use serde_with::serde_as; +use strum::Display; + +#[derive(Debug, Deserialize, Serialize)] +#[serde(transparent)] +struct Config { + wans: Vec +} + +#[derive(Debug, Deserialize, Serialize)] +struct WanConfig { + interface: Option, + #[serde(flatten)] + dns_record: DnsRecord, + providers: Vec, +} + +#[derive(Debug, Display, Deserialize, Serialize)] +#[derive(PartialEq)] +pub enum DnsRecordType { + A, + AAAA +} + +#[serde_as] +#[derive(Debug, Deserialize, Serialize)] +struct DnsRecord { + #[serde_as(as = "DisplayFromStr")] + fqdn: FQDN, + #[serde(default = "default_ttl")] + ttl: u32, + #[serde(default = "default_record_type")] + record_type: DnsRecordType, +} + +fn default_record_type() -> DnsRecordType { + DnsRecordType::A +} +fn default_ttl() -> u32 { + 300 +} + +#[cfg(test)] +mod tests { + use std::error::Error; + use std::fs::{read_dir, File}; + use std::io::BufReader; + use super::*; + use serde_json::json; + use std::str::FromStr; + use crate::dyndns_service::DynDnsProvider::GANDI; + use crate::dyndns_service::gandi::Gandi; + + #[test] + fn check_minimal_config() { + let input = json!({ + "fqdn": "dyn.domain.com", + "providers": [ { + "type": "GANDI", + "api_key": "SOME-API-KEY", + } ] + }); + + let wan_config = serde_json::from_value::(input).unwrap(); + + assert_eq!( + wan_config.dns_record.fqdn, + FQDN::from_str("dyn.domain.com").unwrap() + ); + assert_eq!(wan_config.interface, None); + + assert_eq!(wan_config.providers.len(), 1); + let expected = Gandi::new("SOME-API-KEY".to_string()); + let actual = wan_config.providers.get(0).unwrap(); + assert_eq!(&GANDI(expected), actual); + } + + #[test] + fn check_defaults_on_dns_record_deserialization() { + let input = json!({ + "fqdn": "dyn.mydomain.com", + }); + + let dns_record = serde_json::from_value::(input).unwrap(); + + assert_eq!(dns_record.record_type, default_record_type()); + assert_eq!(dns_record.ttl, default_ttl()); + + assert_eq!(dns_record.fqdn, FQDN::from_str("dyn.mydomain.com").unwrap()); + } + + #[test] + fn check_file_configs() -> Result<(), Box> { + let path = std::path::Path::new("test"); + for entry in read_dir(path)? { + let entry = entry?; + let test_file_path = entry.path(); + if test_file_path.extension().unwrap_or_default() != "json" { + continue; + } + + let file = File::open(test_file_path)?; + let reader = BufReader::new(file); + + let actual: Config = serde_json::from_reader(reader)?; + assert_eq!(actual.wans.len(), 2); + } + Ok(()) + } + +} -- cgit v1.2.3