1use crate::error::{ConstraintError, PaneError, TreeError};
2use crate::node::PanelId;
3use crate::validate::{check_f32_non_negative, float_invalid_to_constraint};
4
5#[derive(Default)]
7pub struct PanelIdGenerator {
8 counter: u32,
9}
10
11impl PanelIdGenerator {
12 pub fn new() -> Self {
14 Self::default()
15 }
16
17 pub fn high_water(&self) -> u32 {
19 self.counter
20 }
21
22 pub fn next_id(&mut self) -> Result<PanelId, PaneError> {
26 let id = PanelId::from_raw(self.counter);
27 self.counter = self
28 .counter
29 .checked_add(1)
30 .ok_or(PaneError::InvalidTree(TreeError::PanelIdExhausted))?;
31 Ok(id)
32 }
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Default)]
37#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
38pub struct Constraints {
39 pub grow: Option<f32>,
41 pub fixed: Option<f32>,
43 pub min: Option<f32>,
45 pub max: Option<f32>,
47}
48
49impl Constraints {
50 pub fn min(mut self, value: f32) -> Self {
52 self.min = Some(value);
53 self
54 }
55
56 pub fn max(mut self, value: f32) -> Self {
58 self.max = Some(value);
59 self
60 }
61
62 pub fn validate(&self) -> Result<(), PaneError> {
64 Self::reject_bad_f32("grow", self.grow)?;
65 Self::reject_bad_f32("fixed", self.fixed)?;
66 Self::reject_bad_f32("min", self.min)?;
67 Self::reject_bad_f32("max", self.max)?;
68
69 match (self.grow, self.fixed, self.min, self.max) {
70 (Some(_), Some(_), _, _) => Err(PaneError::InvalidConstraint(
71 ConstraintError::GrowFixedExclusive,
72 )),
73 (_, _, Some(lo), Some(hi)) if lo > hi => {
74 Err(PaneError::InvalidConstraint(ConstraintError::MinExceedsMax))
75 }
76 _ => Ok(()),
77 }
78 }
79
80 fn reject_bad_f32(name: &'static str, value: Option<f32>) -> Result<(), PaneError> {
81 let Some(v) = value else { return Ok(()) };
82 check_f32_non_negative(v)
83 .map_err(|e| PaneError::InvalidConstraint(float_invalid_to_constraint(name, e)))
84 }
85}
86
87pub fn grow(value: f32) -> Constraints {
89 Constraints {
90 grow: Some(value),
91 ..Constraints::default()
92 }
93}
94
95pub fn fixed(value: f32) -> Constraints {
97 Constraints {
98 fixed: Some(value),
99 ..Constraints::default()
100 }
101}