[WIP] A simple wake-on-lan service

add support for configuring the ip address for a device. this will be used to ping the device for status

vielle.dev 23adae84 cb6a0d73

verified
+15 -20
+9 -3
src/config.rs
··· 2 2 use std::{collections::HashMap, fs::File, io::Read, path::PathBuf}; 3 3 use thiserror::Error; 4 4 5 - #[derive(Deserialize, Debug)] 5 + #[derive(Deserialize, Debug, Clone)] 6 6 pub struct Config { 7 7 #[serde(default = "default_binding")] 8 8 pub binding: String, 9 - #[serde(deserialize_with = "crate::mac::deserialize_mac_hashmap")] 10 - pub targets: HashMap<String, crate::mac::MacAddress>, 9 + pub targets: HashMap<String, Target>, 10 + } 11 + 12 + #[derive(Deserialize, Debug, Clone)] 13 + pub struct Target { 14 + #[serde(deserialize_with = "crate::mac::deserialize_mac")] 15 + pub mac: crate::mac::MacAddress, 16 + pub ip: Option<String>, 11 17 } 12 18 13 19 fn default_binding() -> String {
+1 -12
src/mac.rs
··· 1 - use std::{collections::HashMap, fmt::Display, net::UdpSocket, num::ParseIntError, str::FromStr}; 1 + use std::{fmt::Display, net::UdpSocket, num::ParseIntError, str::FromStr}; 2 2 3 3 use serde::{Deserialize, Deserializer, de::Error}; 4 4 use thiserror::Error; ··· 75 75 { 76 76 MacAddress::from_str(&String::deserialize(de)?).map_err(Error::custom) 77 77 } 78 - 79 - pub fn deserialize_mac_hashmap<'de, D>(de: D) -> Result<HashMap<String, MacAddress>, D::Error> 80 - where 81 - D: Deserializer<'de>, 82 - { 83 - HashMap::<String, String>::deserialize(de)? 84 - .into_iter() 85 - .map::<Result<_, MacAddressParseError>, _>(|(k, v)| Ok((k, MacAddress::from_str(&v)?))) 86 - .collect::<Result<_, _>>() 87 - .map_err(Error::custom) 88 - }
+1 -1
src/main.rs
··· 20 20 let config = config::Config::load(PathBuf::from("./wol.toml"))?; 21 21 println!("Binding to {}", config.binding); 22 22 for (k, v) in &config.targets { 23 - println!("target: {k}: {v}"); 23 + println!("target: {k}: {} ({:?})", v.mac, v.ip); 24 24 } 25 25 let listener = tokio::net::TcpListener::bind(config.binding).await?; 26 26 axum::serve(listener, server::router(config.targets)).await?;
+4 -4
src/server/mod.rs
··· 8 8 }; 9 9 use serde::Deserialize; 10 10 11 - use crate::mac::MacAddress; 11 + use crate::{config::Target, mac::MacAddress}; 12 12 13 - fn index(map: &HashMap<String, MacAddress>) -> String { 13 + fn index(map: &HashMap<String, Target>) -> String { 14 14 include_str!("index.html").replace( 15 15 "<button-template></button-template>", 16 16 &map.into_iter() 17 17 .map(|(k, v)| { 18 18 format!( 19 19 r#"<li><button onclick="wake('{}')">{}</button></li>"#, 20 - v.to_string(), 20 + v.mac.to_string(), 21 21 k 22 22 ) 23 23 }) ··· 43 43 }) 44 44 } 45 45 46 - pub fn router(map: HashMap<String, MacAddress>) -> Router { 46 + pub fn router(map: HashMap<String, Target>) -> Router { 47 47 Router::new() 48 48 .route( 49 49 "/",