use clap::Parser; use gethostname::gethostname; use serde::Deserialize; use std::net::IpAddr; #[derive(Parser, Debug)] pub enum MessageKind { Hello, Reboot, } #[derive(Deserialize, Debug)] pub struct MessageBuilder { pub from: Option, pub to: Option, pub body: Option, } impl MessageBuilder { fn new() -> Self { Self { from: None, to: None, body: None, } } pub fn from(mut self, from: impl Into) -> Self { self.from = Some(from.into()); self } pub fn to(mut self, to: impl Into) -> Self { self.to = Some(to.into()); self } pub fn with_action(mut self, action: MessageKind, config: &crate::config::Config) -> Self { let body = match action { MessageKind::Reboot => reboot(&config.reboot), MessageKind::Hello => hello(), }; self.body = Some(body); self } pub fn build(self) -> Message { let Self { from, to, body } = self; Message { from, to, body } } } #[derive(Deserialize, Debug)] pub struct Message { pub from: Option, pub to: Option, pub body: Option, } impl Message { pub fn builder() -> MessageBuilder { MessageBuilder::new() } } fn hello() -> String { String::from("hello world") } fn reboot(config: &crate::config::RebootConfig) -> String { let ipaddr_v4 = if_addrs::get_if_addrs() .unwrap_or_default() .into_iter() .find(|iface| iface.name == config.ifname) .and_then(|iface| match iface.ip() { IpAddr::V4(addr) => Some(addr), IpAddr::V6(_) => None, }) .expect("there should be an ipv4 address"); let hostname = gethostname() .into_string() .expect("failed to get the hostname"); format!( "{} has rebooted. The IP address for the interface {} is {}.", hostname, config.ifname, ipaddr_v4 ) } #[cfg(test)] mod test { use crate::message::Message; #[test] fn test_create_message() { let from = "1".to_string(); let to = "2".to_string(); let account_sid = "test".to_string(); let auth_token = "test".to_string(); let cfg = crate::config::Config { to, from, account_sid, auth_token, reboot: crate::config::RebootConfig { ifname: "eth0".to_string(), }, hello: crate::config::HelloConfig {}, }; let msg = Message::builder() .from("1") .to("2") .with_action(crate::message::MessageKind::Hello, &cfg) .build(); assert_eq!(msg.body, Some("hello world".to_string())); } }