rtimelog 1.1.1

System for tracking time in a text-log-based format.
Documentation
//! Representation of charts for timelog
//!
//! # Description
//!
//! Support for both pie charts (of projects and tasks in a project), and
//! a bar graph of tasks displayed hourly.

pub mod colors;
pub mod day;
pub mod histogram;
pub mod legend;
pub mod pie;
pub mod pie_data;
pub mod tag_percent;

/// The [`ColorIter`] type represents an ordered list of colors to use for
/// building a pie chart.
pub use colors::ColorIter;
/// The [`DayHours`] type holds project-based task events for building an
/// hourly bar graph of the projects worked.
pub use day::DayHours;
/// The [`BarGraph`] type holds configuration data needed to display an
/// hourly bar graph of the projects worked.
pub use histogram::BarGraph;
/// The [`Legend`] type formats the labels for a legend on the pie chart.
pub use legend::Legend;
/// The [`PieChart`] type holds the configuration data needed to display a
/// pie chart.
pub use pie::PieChart;
/// The [`PieData`] type holds the data for a pie chart.
pub use pie_data::PieData;
/// The [`Percent`] type represents a percentage greater than 0.0 up to 100.0
pub use tag_percent::Percent;
/// The [`TagPercent`] type holds a labeled percent value used in constructing
/// pie charts.
pub use tag_percent::TagPercent;
/// The [`Percentages`] type is a vector of [`TagPercent`]s.
pub type Percentages = Vec<TagPercent>;

pub(crate) mod utils {
    pub(crate) fn format_coord(coord: f32) -> String {
        let s = format!("{coord:.3}");
        s.trim_end_matches('0').trim_end_matches('.').to_string()
    }
}

#[cfg(test)]
mod tests {
    use assert2::assert;
    use rstest::rstest;

    use super::utils::*;

    #[rstest]
    #[case(0.0,       "0",     "zero")]
    #[case(1.2345678, "1.235", "three decimal")]
    #[case(10.5,      "10.5",  "half")]
    #[case(10.25,     "10.25", "quarter")]
    fn test_format_coord(#[case]coord: f32, #[case]expected: &str, #[case]msg: &str) {
        assert!(format_coord(coord).as_str() == expected, "{msg}");
    }
}