steel_utils/value_providers/
vertical_anchor.rs1use serde::{Deserialize, Deserializer, de::Error as _};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum VerticalAnchor {
7 Absolute(i32),
9 AboveBottom(i32),
11 BelowTop(i32),
13}
14
15impl VerticalAnchor {
16 #[must_use]
20 pub const fn resolve_y(self, min_y: i32, height: i32) -> i32 {
21 match self {
22 Self::Absolute(y) => y,
23 Self::AboveBottom(offset) => min_y + offset,
24 Self::BelowTop(offset) => min_y + height - 1 - offset,
25 }
26 }
27}
28
29impl<'de> Deserialize<'de> for VerticalAnchor {
30 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
31 #[derive(Deserialize)]
32 #[serde(deny_unknown_fields)]
33 struct Raw {
34 #[serde(default)]
35 absolute: Option<i32>,
36 #[serde(default)]
37 above_bottom: Option<i32>,
38 #[serde(default)]
39 below_top: Option<i32>,
40 }
41 let raw = Raw::deserialize(d)?;
42 match (raw.absolute, raw.above_bottom, raw.below_top) {
43 (Some(y), None, None) => Ok(Self::Absolute(y)),
44 (None, Some(o), None) => Ok(Self::AboveBottom(o)),
45 (None, None, Some(o)) => Ok(Self::BelowTop(o)),
46 (None, None, None) => Err(D::Error::custom(
47 "VerticalAnchor requires exactly one of absolute/above_bottom/below_top",
48 )),
49 _ => Err(D::Error::custom(
50 "VerticalAnchor must have exactly one of absolute/above_bottom/below_top",
51 )),
52 }
53 }
54}