From cb071f4a7c7a6be5602b91f79d32128c5885b9b4 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Fri, 8 Aug 2025 13:38:16 -0700 Subject: [PATCH] do smarter IP deserialization --- src/app/widgets.rs | 2 +- src/config.rs | 34 ++++++++++++++++++++-------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/app/widgets.rs b/src/app/widgets.rs index 46e9f57..512ea6d 100644 --- a/src/app/widgets.rs +++ b/src/app/widgets.rs @@ -147,7 +147,7 @@ impl Widget for &mut App { buf, ); network_info( - &self.service.config.local_ip_addr.unwrap_or([0u8; 4].into()), + &self.service.config.local_ip_addr, footer_left.inner(footer_margin), buf, ); diff --git a/src/config.rs b/src/config.rs index f4d705f..792cea3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -9,7 +9,7 @@ use figment::{ providers::{Format, Serialized, Toml}, }; use local_ip_address::local_ip; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use crate::{ DEFAULT_PORT, MULTICAST_IP, @@ -22,8 +22,8 @@ pub struct Config { pub multicast_addr: SocketAddrV4, pub download_dir: PathBuf, pub data_dir: PathBuf, - #[serde(skip_serializing)] - pub local_ip_addr: Option, + #[serde(deserialize_with = "deserialize_local_addr")] + pub local_ip_addr: Ipv4Addr, pub device: Device, } @@ -33,7 +33,7 @@ impl Default for Config { multicast_addr: SocketAddrV4::new(MULTICAST_IP, DEFAULT_PORT), download_dir: Default::default(), data_dir: Default::default(), - local_ip_addr: None, + local_ip_addr: Ipv4Addr::from_bits(0), device: Default::default(), } } @@ -47,10 +47,6 @@ impl Config { let config_file = dirs.config_dir().join("jocalsend.toml"); let data_dir = dirs.data_local_dir().join("jocalsend"); - let IpAddr::V4(local_ip_addr) = local_ip()? else { - return Err(LocalSendError::IPv6Unsupported); - }; - let key = data_dir.join("key.pem"); let cert = data_dir.join("cert.pem"); let fingerprint = if data_dir.exists() { @@ -67,8 +63,8 @@ impl Config { let config = Self { multicast_addr: SocketAddrV4::new(MULTICAST_IP, DEFAULT_PORT), + local_ip_addr: get_local_ip_addr(), download_dir, - local_ip_addr: Some(local_ip_addr), data_dir, device: Device { alias: rustix::system::uname() @@ -80,7 +76,7 @@ impl Config { }, }; - let mut config = if !config_file.exists() { + let config = if !config_file.exists() { log::info!("creating config file at {config_file:?}"); std::fs::write(&config_file, toml::to_string(&config)?)?; config @@ -92,10 +88,6 @@ impl Config { .map_err(Box::new)? // boxed because the error size from figment is large }; - if config.local_ip_addr.is_none() { - config.local_ip_addr = Some(local_ip_addr); - } - log::info!("using config: {config:?}"); Ok(config) @@ -118,3 +110,17 @@ fn gen_ssl(key: &Path, cert: &Path) -> Result { std::fs::write(cert, cert_text)?; Ok(sha256::digest(key_text)) } + +fn deserialize_local_addr<'de, D>(_: D) -> std::result::Result +where + D: Deserializer<'de>, +{ + Ok(get_local_ip_addr()) +} + +fn get_local_ip_addr() -> Ipv4Addr { + let IpAddr::V4(local_ip_addr) = local_ip().unwrap_or(IpAddr::V4(Ipv4Addr::from_bits(0))) else { + panic!("IPv6 is unsupported"); + }; + local_ip_addr +}