Skip to main content

cbtop/grammar/
scales.rs

1//! Resource scaling traits and implementations.
2
3use super::error::{GrammarError, GrammarResult};
4
5/// Resource scaling trait (analogous to graphics Scale<D, R>)
6pub trait ResourceScale<D, R> {
7    /// Scale a request from domain to range
8    fn scale(&self, request: D) -> R;
9    /// Get domain bounds
10    fn domain(&self) -> (D, D);
11    /// Get range bounds
12    fn range(&self) -> (R, R);
13}
14
15/// Linear resource scaling
16#[derive(Debug, Clone)]
17pub struct LinearResourceScale {
18    domain: (f64, f64),
19    range: (f64, f64),
20}
21
22impl LinearResourceScale {
23    /// Create new linear scale
24    pub fn new(domain: (f64, f64), range: (f64, f64)) -> GrammarResult<Self> {
25        if domain.0 >= domain.1 {
26            return Err(GrammarError::InvalidScaleDomain {
27                min: domain.0,
28                max: domain.1,
29            });
30        }
31        Ok(Self { domain, range })
32    }
33}
34
35impl ResourceScale<f64, f64> for LinearResourceScale {
36    fn scale(&self, request: f64) -> f64 {
37        let t = (request - self.domain.0) / (self.domain.1 - self.domain.0);
38        self.range.0 + t * (self.range.1 - self.range.0)
39    }
40
41    fn domain(&self) -> (f64, f64) {
42        self.domain
43    }
44
45    fn range(&self) -> (f64, f64) {
46        self.range
47    }
48}
49
50/// Logarithmic resource scaling (for exponential resources)
51#[derive(Debug, Clone)]
52pub struct LogResourceScale {
53    base: f64,
54    domain: (f64, f64),
55    range: (f64, f64),
56}
57
58impl LogResourceScale {
59    /// Create new log scale
60    pub fn new(base: f64, domain: (f64, f64), range: (f64, f64)) -> GrammarResult<Self> {
61        if domain.0 >= domain.1 {
62            return Err(GrammarError::InvalidScaleDomain {
63                min: domain.0,
64                max: domain.1,
65            });
66        }
67        Ok(Self {
68            base,
69            domain,
70            range,
71        })
72    }
73}
74
75impl ResourceScale<f64, f64> for LogResourceScale {
76    fn scale(&self, request: f64) -> f64 {
77        let log_request = request.log(self.base);
78        let log_min = self.domain.0.log(self.base);
79        let log_max = self.domain.1.log(self.base);
80        let t = (log_request - log_min) / (log_max - log_min);
81        self.range.0 + t * (self.range.1 - self.range.0)
82    }
83
84    fn domain(&self) -> (f64, f64) {
85        self.domain
86    }
87
88    fn range(&self) -> (f64, f64) {
89        self.range
90    }
91}