aboutsummaryrefslogblamecommitdiff
path: root/src/message.rs
blob: 5fbd5faa222387d558e88413cc2dcc9c086d2681 (plain) (tree)





















































































































                                                                                               
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()));
    }
}