diff --git a/burrow/src/database.rs b/burrow/src/database.rs index e8119481..9a9aac3f 100644 --- a/burrow/src/database.rs +++ b/burrow/src/database.rs @@ -105,7 +105,7 @@ pub fn dump_interface(conn: &Connection, config: &Config) -> Result<()> { cif.private_key, to_lst(&cif.dns), to_lst(&cif.address), - cif.listen_port, + cif.listen_port.unwrap_or(51820), cif.mtu ])?; let interface_id = conn.last_insert_rowid(); diff --git a/burrow/src/wireguard/config.rs b/burrow/src/wireguard/config.rs index 1d9315a0..5766675e 100644 --- a/burrow/src/wireguard/config.rs +++ b/burrow/src/wireguard/config.rs @@ -48,7 +48,7 @@ pub struct Peer { pub struct Interface { pub private_key: String, pub address: Vec, - pub listen_port: u32, + pub listen_port: Option, pub dns: Vec, pub mtu: Option, } @@ -102,7 +102,7 @@ impl Default for Config { interface: Interface { private_key: "OEPVdomeLTxTIBvv3TYsJRge0Hp9NMiY0sIrhT8OWG8=".into(), address: vec!["10.13.13.2/24".into()], - listen_port: 51820, + listen_port: Some(51820), dns: Default::default(), mtu: Default::default(), }, @@ -118,11 +118,11 @@ impl Default for Config { } } -fn props_get(props: &Properties, key: &str) -> T +fn props_get(props: &Properties, key: &str) -> Result where - T: From, + T: TryFrom, { - IniField::from(props.get(key)).into() + IniField::try_from(props.get(key))?.try_into() } impl TryFrom<&Properties> for Interface { @@ -130,11 +130,11 @@ impl TryFrom<&Properties> for Interface { fn try_from(props: &Properties) -> Result { Ok(Self { - private_key: props_get(props, "PrivateKey"), - address: props_get(props, "Address"), - listen_port: props_get(props, "ListenPort"), - dns: props_get(props, "DNS"), - mtu: props_get(props, "MTU"), + private_key: props_get(props, "PrivateKey")?, + address: props_get(props, "Address")?, + listen_port: props_get(props, "ListenPort")?, + dns: props_get(props, "DNS")?, + mtu: props_get(props, "MTU")?, }) } } @@ -144,12 +144,12 @@ impl TryFrom<&Properties> for Peer { fn try_from(props: &Properties) -> Result { Ok(Self { - public_key: props_get(props, "PublicKey"), - preshared_key: props_get(props, "PresharedKey"), - allowed_ips: props_get(props, "AllowedIPs"), - endpoint: props_get(props, "Endpoint"), - persistent_keepalive: props_get(props, "PersistentKeepalive"), - name: props_get(props, "Name"), + public_key: props_get(props, "PublicKey")?, + preshared_key: props_get(props, "PresharedKey")?, + allowed_ips: props_get(props, "AllowedIPs")?, + endpoint: props_get(props, "Endpoint")?, + persistent_keepalive: props_get(props, "PersistentKeepalive")?, + name: props_get(props, "Name")?, }) } } diff --git a/burrow/src/wireguard/inifield.rs b/burrow/src/wireguard/inifield.rs index fb65a20b..946868de 100644 --- a/burrow/src/wireguard/inifield.rs +++ b/burrow/src/wireguard/inifield.rs @@ -1,54 +1,76 @@ use std::str::FromStr; +use anyhow::{Error, Result}; + pub struct IniField(String); impl FromStr for IniField { - type Err = anyhow::Error; + type Err = Error; fn from_str(s: &str) -> Result { Ok(Self(s.to_string())) } } -impl From for Vec { - fn from(field: IniField) -> Self { - field.0.split(",").map(|s| s.to_string()).collect() +impl TryFrom for Vec { + type Error = Error; + + fn try_from(field: IniField) -> Result { + Ok(field.0.split(',').map(|s| s.trim().to_string()).collect()) } } -impl From for u32 { - fn from(value: IniField) -> Self { - value.0.parse().unwrap() +impl TryFrom for u32 { + type Error = Error; + + fn try_from(value: IniField) -> Result { + value.0.parse().map_err(Error::from) } } -impl From for Option { - fn from(value: IniField) -> Self { - Some(value.0.parse().unwrap()) +impl TryFrom for Option { + type Error = Error; + + fn try_from(value: IniField) -> Result { + if value.0.is_empty() { + Ok(None) + } else { + value.0.parse().map(Some).map_err(Error::from) + } } } -impl From for String { - fn from(value: IniField) -> Self { - value.0 +impl TryFrom for String { + type Error = Error; + + fn try_from(value: IniField) -> Result { + Ok(value.0) } } -impl From for Option { - fn from(value: IniField) -> Self { - Some(value.0) +impl TryFrom for Option { + type Error = Error; + + fn try_from(value: IniField) -> Result { + if value.0.is_empty() { + Ok(None) + } else { + Ok(Some(value.0)) + } } } -impl From> for IniField +impl TryFrom> for IniField where T: ToString, { - fn from(value: Option) -> Self { - match value { + type Error = Error; + + fn try_from(value: Option) -> Result { + Ok(match value { Some(v) => Self(v.to_string()), - None => Self("".to_string()), - } + None => Self(String::new()), + }) } }