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<String>,
pub to: Option<String>,
pub body: Option<String>,
}
impl MessageBuilder {
fn new() -> Self {
Self {
from: None,
to: None,
body: None,
}
}
pub fn from(mut self, from: impl Into<String>) -> Self {
self.from = Some(from.into());
self
}
pub fn to(mut self, to: impl Into<String>) -> 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<String>,
pub to: Option<String>,
pub body: Option<String>,
}
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()));
}
}