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