1use core::ops::Add;
2
3use crate::number::Number;
4use crate::style;
5
6#[derive(Debug, Copy, Clone, PartialEq)]
7#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8#[cfg_attr(feature = "serde", serde(default))]
9#[cfg_attr(all(feature = "serde", feature = "serde_kebab_case"), serde(rename_all = "kebab-case"))]
10#[cfg_attr(all(feature = "serde", feature = "serde_camel_case"), serde(rename_all = "camelCase"))]
11pub struct Rect<T> {
12 pub start: T,
13 pub end: T,
14 pub top: T,
15 pub bottom: T,
16}
17
18impl<T> Rect<T> {
19 pub(crate) fn map<R, F>(self, f: F) -> Rect<R>
20 where
21 F: Fn(T) -> R,
22 {
23 Rect { start: f(self.start), end: f(self.end), top: f(self.top), bottom: f(self.bottom) }
24 }
25}
26
27impl<T> Rect<T>
28where
29 T: Add<Output = T> + Copy + Clone,
30{
31 pub(crate) fn horizontal(&self) -> T {
32 self.start + self.end
33 }
34
35 pub(crate) fn vertical(&self) -> T {
36 self.top + self.bottom
37 }
38
39 pub(crate) fn main(&self, direction: style::FlexDirection) -> T {
40 match direction {
41 style::FlexDirection::Row | style::FlexDirection::RowReverse => self.start + self.end,
42 style::FlexDirection::Column | style::FlexDirection::ColumnReverse => self.top + self.bottom,
43 }
44 }
45
46 pub(crate) fn cross(&self, direction: style::FlexDirection) -> T {
47 match direction {
48 style::FlexDirection::Row | style::FlexDirection::RowReverse => self.top + self.bottom,
49 style::FlexDirection::Column | style::FlexDirection::ColumnReverse => self.start + self.end,
50 }
51 }
52}
53
54impl<T> Rect<T>
55where
56 T: Copy + Clone,
57{
58 pub(crate) fn main_start(&self, direction: style::FlexDirection) -> T {
59 match direction {
60 style::FlexDirection::Row | style::FlexDirection::RowReverse => self.start,
61 style::FlexDirection::Column | style::FlexDirection::ColumnReverse => self.top,
62 }
63 }
64
65 pub(crate) fn main_end(&self, direction: style::FlexDirection) -> T {
66 match direction {
67 style::FlexDirection::Row | style::FlexDirection::RowReverse => self.end,
68 style::FlexDirection::Column | style::FlexDirection::ColumnReverse => self.bottom,
69 }
70 }
71
72 pub(crate) fn cross_start(&self, direction: style::FlexDirection) -> T {
73 match direction {
74 style::FlexDirection::Row | style::FlexDirection::RowReverse => self.top,
75 style::FlexDirection::Column | style::FlexDirection::ColumnReverse => self.start,
76 }
77 }
78
79 pub(crate) fn cross_end(&self, direction: style::FlexDirection) -> T {
80 match direction {
81 style::FlexDirection::Row | style::FlexDirection::RowReverse => self.bottom,
82 style::FlexDirection::Column | style::FlexDirection::ColumnReverse => self.end,
83 }
84 }
85}
86
87#[derive(Debug, Copy, Clone, PartialEq)]
88#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
89#[cfg_attr(feature = "serde", serde(default))]
90#[cfg_attr(all(feature = "serde", feature = "serde_kebab_case"), serde(rename_all = "kebab-case"))]
91#[cfg_attr(all(feature = "serde", feature = "serde_camel_case"), serde(rename_all = "camelCase"))]
92pub struct Size<T> {
93 pub width: T,
94 pub height: T,
95}
96
97impl Size<()> {
98 pub fn undefined() -> Size<Number> {
99 Size { width: Number::Undefined, height: Number::Undefined }
100 }
101}
102
103impl<T> Size<T> {
104 pub fn map<R, F>(self, f: F) -> Size<R>
105 where
106 F: Fn(T) -> R,
107 {
108 Size { width: f(self.width), height: f(self.height) }
109 }
110
111 pub(crate) fn set_main(&mut self, direction: style::FlexDirection, value: T) {
112 match direction {
113 style::FlexDirection::Row | style::FlexDirection::RowReverse => self.width = value,
114 style::FlexDirection::Column | style::FlexDirection::ColumnReverse => self.height = value,
115 }
116 }
117
118 pub(crate) fn set_cross(&mut self, direction: style::FlexDirection, value: T) {
119 match direction {
120 style::FlexDirection::Row | style::FlexDirection::RowReverse => self.height = value,
121 style::FlexDirection::Column | style::FlexDirection::ColumnReverse => self.width = value,
122 }
123 }
124
125 pub(crate) fn main(self, direction: style::FlexDirection) -> T {
126 match direction {
127 style::FlexDirection::Row | style::FlexDirection::RowReverse => self.width,
128 style::FlexDirection::Column | style::FlexDirection::ColumnReverse => self.height,
129 }
130 }
131
132 pub(crate) fn cross(self, direction: style::FlexDirection) -> T {
133 match direction {
134 style::FlexDirection::Row | style::FlexDirection::RowReverse => self.height,
135 style::FlexDirection::Column | style::FlexDirection::ColumnReverse => self.width,
136 }
137 }
138}
139
140impl Size<f32> {
141 pub fn zero() -> Self {
142 Self { width: 0.0, height: 0.0 }
143 }
144}
145
146impl Size<style::Dimension> {
147 pub(crate) fn resolve(&self, parent: Size<Number>) -> Size<Number> {
148 Size { width: self.width.resolve(parent.width), height: self.height.resolve(parent.height) }
149 }
150}
151
152#[derive(Debug, Copy, Clone, PartialEq)]
153pub struct Point<T> {
154 pub x: T,
155 pub y: T,
156}
157
158impl Point<f32> {
159 pub fn zero() -> Self {
160 Self { x: 0.0, y: 0.0 }
161 }
162}