bar-rubble 0.5.2

Quickly generate output for viewing in swaybar or similar
Documentation
//! Rubblets are the modules that bar-rubble can load to get different types of infomation to
//! display

use clap::Args;
use handlebars::Handlebars;
use handlebars::JsonValue;
use std::error::Error;

#[cfg(feature = "device")]
pub mod device;
#[cfg(feature = "ip")]
pub mod ip;
#[cfg(feature = "mail")]
pub mod mail;
#[cfg(feature = "mpris")]
pub mod mpris;
#[cfg(feature = "network")]
pub mod network;
#[cfg(feature = "razor")]
pub mod razor;
#[cfg(feature = "weather")]
pub mod weather;
#[cfg(feature = "wireguard")]
pub mod wireguard;

#[derive(Args)]
/// Wraps the arguments to be passed when using ListFormattingStrings
pub struct PrintFormattingStringsArgs {
    pub command: String,
    pub selector: Option<device::SystemStats>,
}

/// Rubblets should return a RubbleResult so we can use the formatter to print result to screen
pub struct RubbleResult {
    pub json_value: Result<JsonValue, Box<dyn Error>>,
    pub default_format: &'static str,
    pub user_format: Option<String>,
}

impl RubbleResult {
    /// Constructor for RubbleResult without any user_format
    /// as this is typically passed in later
    pub fn new(
        json_value: Result<JsonValue, Box<dyn Error>>,
        default_format: &'static str,
    ) -> Self {
        Self {
            json_value: json_value,
            default_format: default_format,
            user_format: None,
        }
    }

    /// Prints RubbleResult to stdout as formatted by user
    /// or using the default format for the rubblet
    pub fn print(&self) {
        let reg = Handlebars::new();
        // there has to be a better way to do this
        let fmt = if self.user_format.is_some() {
            self.user_format.as_ref().unwrap()
        } else {
            self.default_format
        };
        let render = reg.render_template(fmt, &self.json_value.as_ref().unwrap());
        println!("{}", render.unwrap())
    }
}

/// Wraps each of the formatting strings in a {{}} so the user can easily see how to use fmt
/// strings, but leaves a trailing whitespace
///
/// # Examples
///
/// ```
/// let result = rubblets::format_formatting_strings("this is a test");
/// assert_eq!(result, "{{this}} {{is}} {{a}} {{test}} ");
/// ```
pub fn format_formatting_strings(options: &str) -> String {
    options
        .split_whitespace()
        .into_iter()
        .map(|o| format!("{}{}{} ", "{{", o, "}}"))
        .collect()
}

/// Creates the default_format() and formatting_strings() Fn
/// Rubblets can use this macro to reduce boilerplate code
macro_rules! avaliable_formattings {
    (
        $default_format:expr,
        $formatting_strings:expr
    ) => {
        pub fn default_format() -> &'static str {
            ($default_format)
        }
        pub fn formatting_strings() -> &'static str {
            ($formatting_strings)
        }
    };
}

pub(crate) use avaliable_formattings;