diff options
| author | Gus Power <gus@infinitesidequests.com> | 2025-05-14 13:21:08 +0100 |
|---|---|---|
| committer | Gus Power <gus@infinitesidequests.com> | 2025-05-14 13:21:08 +0100 |
| commit | dd1483cb6d9c060a17dc68357975de2b1ec09c08 (patch) | |
| tree | dae1850e9ab89894fd217cfcd32ce31d91a767f8 /src/config.rs | |
| parent | 87c3219c0e6c7f374cf117eb1990dd41e196710a (diff) | |
reduce size of DnsRecordType (introduce enum), add overall config w/ supporting "full" test file.
Diffstat (limited to 'src/config.rs')
| -rw-r--r-- | src/config.rs | 115 |
1 files changed, 115 insertions, 0 deletions
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<WanConfig> +} + +#[derive(Debug, Deserialize, Serialize)] +struct WanConfig { + interface: Option<String>, + #[serde(flatten)] + dns_record: DnsRecord, + providers: Vec<DynDnsProvider>, +} + +#[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::<WanConfig>(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::<DnsRecord>(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<dyn Error>> { + 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(()) + } + +} |
