1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
use std::io::{self, Write};

use colored::Colorize;
use islam::chrono::{DateTime, Local};

use crate::error::BilalError;
use islam::pray::PrayerTimes;

pub struct Printer {
    prayers: PrayerTimes,
    show_color: bool,
    json_format: bool,
}

impl Printer {
    pub const fn new(prayers: PrayerTimes, show_color: bool, json_format: bool) -> Self {
        Self {
            prayers,
            show_color,
            json_format,
        }
    }
    /// Show all prayers info.
    pub fn all(&self) -> Result<(), BilalError> {
        let prayers = self.prayers;

        let fmt_output = |name: &str, prayer: DateTime<Local>| {
            format!("{}: {}", name, prayer.format("%H:%M").to_string())
        };

        Self::print(&fmt_output("Fajr", prayers.fajr));
        Self::print(&fmt_output("Sherook", prayers.sherook));
        Self::print(&fmt_output("Dohr", prayers.dohr));
        Self::print(&fmt_output("Asr", prayers.asr));
        Self::print(&fmt_output("Mghreb", prayers.maghreb));
        Self::print(&fmt_output("Ishaa", prayers.ishaa));
        Self::print(&fmt_output(
            "Fist third of night",
            prayers.first_third_of_night,
        ));
        Self::print(&fmt_output("Midnight", prayers.midnight));
        Self::print(&fmt_output(
            "Last third of night",
            prayers.last_third_of_night,
        ));

        Ok(())
    }
    /// Show current prayer info
    pub fn current(&self) -> Result<(), BilalError> {
        let prayers = self.prayers;
        let prayer = prayers.current();
        let (hour, minute) = prayers.time_remaining();

        let remaining_fmt = {
            if hour == 0 {
                format!("({} minutes)", minute)
            } else {
                format!("({}:{} hours)", hour, minute)
            }
        };

        // default
        let mut prayer_fmt = format!("{} {}", prayer.name(), remaining_fmt);
        let state = {
            if hour == 0 && minute < 30 {
                "Critical"
            } else {
                "Info"
            }
        };

        // JSON
        if self.json_format {
            prayer_fmt = format!(
                r#"{{"icon": "{}", "state": "{}", "text": "{} {}"}}"#,
                "bilal", state, "\u{23fa} ", prayer_fmt
            )
        }
        // color
        if self.show_color && state == "Critical" && !self.json_format {
            prayer_fmt = format!("{}", prayer_fmt.red());
        }
        Self::print(&prayer_fmt);
        Ok(())
    }
    /// Show next prayer info
    pub fn next(&self) -> Result<(), BilalError> {
        let prayers = self.prayers;
        let prayer = prayers.next();
        let time = prayers.time(prayer);

        let time_fmt = time.format("%H:%M").to_string();

        // default
        let mut prayer_fmt = format!("{} ({})", prayer.name(), time_fmt);
        // JSON
        let state = "Info";
        if self.json_format {
            prayer_fmt = format!(
                r#"{{"icon": "{}", "state": "{}", "text": "{} {}"}}"#,
                "bilal", state, "\u{25b6}", prayer_fmt
            )
        }
        Self::print(&prayer_fmt);
        Ok(())
    }
    fn print(prayer_fmt: &str) {
        writeln!(io::stdout(), "{}", prayer_fmt).ok();
    }
}