Skip to main content

dear_implot/
histogram_bins.rs

1/// Binning methods for histograms
2#[repr(i32)]
3#[derive(Copy, Clone, Debug, PartialEq, Eq)]
4pub enum BinMethod {
5    Sqrt = -1,
6    Sturges = -2,
7    Rice = -3,
8    Scott = -4,
9}
10
11/// Histogram bin selector.
12///
13/// ImPlot uses positive integers for concrete bin counts and negative integer
14/// sentinels for automatic binning methods. This type keeps those two meanings
15/// explicit in the safe Rust API.
16#[derive(Copy, Clone, Debug, PartialEq, Eq)]
17pub enum HistogramBins {
18    /// Use a concrete positive bin count.
19    Count(usize),
20    /// Use an automatic ImPlot binning method.
21    Method(BinMethod),
22}
23
24impl HistogramBins {
25    /// The default ImPlot histogram binning method.
26    pub const DEFAULT: Self = Self::Method(BinMethod::Sturges);
27
28    /// Create a concrete positive bin count.
29    pub const fn count(count: usize) -> Self {
30        Self::Count(count)
31    }
32
33    /// Create an automatic binning-method selector.
34    pub const fn method(method: BinMethod) -> Self {
35        Self::Method(method)
36    }
37
38    pub(crate) fn raw(self, caller: &str) -> i32 {
39        match self {
40            Self::Count(count) => {
41                assert!(count > 0, "{caller} bin count must be positive");
42                i32::try_from(count)
43                    .unwrap_or_else(|_| panic!("{caller} bin count exceeded ImPlot's i32 range"))
44            }
45            Self::Method(method) => method as i32,
46        }
47    }
48}
49
50impl Default for HistogramBins {
51    fn default() -> Self {
52        Self::DEFAULT
53    }
54}
55
56impl From<usize> for HistogramBins {
57    fn from(count: usize) -> Self {
58        Self::Count(count)
59    }
60}
61
62impl From<BinMethod> for HistogramBins {
63    fn from(method: BinMethod) -> Self {
64        Self::Method(method)
65    }
66}