use crate::render::Color;
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub(crate) enum Orientation {
Horizontal(f64),
Vertical(f64),
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Rule {
pub(crate) orientation: Orientation,
pub(crate) color: Option<Color>,
pub(crate) label: Option<String>,
}
impl Rule {
pub fn h(y: f64) -> Rule {
let rule = Rule {
orientation: Orientation::Horizontal(y),
color: None,
label: None,
};
rule.validate().expect("Rule::h requires a finite position");
rule
}
pub fn v(x: f64) -> Rule {
let rule = Rule {
orientation: Orientation::Vertical(x),
color: None,
label: None,
};
rule.validate().expect("Rule::v requires a finite position");
rule
}
#[must_use]
pub fn color(mut self, color: Color) -> Rule {
self.color = Some(color);
self
}
#[must_use]
pub fn label(mut self, label: impl Into<String>) -> Rule {
self.label = Some(label.into());
self
}
pub(crate) fn validate(&self) -> crate::Result<()> {
let position = match self.orientation {
Orientation::Horizontal(value) | Orientation::Vertical(value) => value,
};
if position.is_finite() {
Ok(())
} else {
Err(crate::Error::InvalidParameter {
detail: "a Rule position must be finite",
})
}
}
}
#[cfg(test)]
#[path = "tests/rule_tests.rs"]
mod tests;