1use fret_core::Px;
2
3use crate::style::MarginEdgeRefinement;
4use crate::{MetricRef, SignedMetricRef, Space};
5
6#[derive(Debug, Clone, PartialEq)]
11pub struct Edges4<T> {
12 pub top: T,
13 pub right: T,
14 pub bottom: T,
15 pub left: T,
16}
17
18impl<T> Edges4<T> {
19 pub fn trbl(top: T, right: T, bottom: T, left: T) -> Self {
20 Self {
21 top,
22 right,
23 bottom,
24 left,
25 }
26 }
27
28 pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Edges4<U> {
29 Edges4 {
30 top: f(self.top),
31 right: f(self.right),
32 bottom: f(self.bottom),
33 left: f(self.left),
34 }
35 }
36}
37
38impl<T: Clone> Edges4<T> {
39 pub fn all(value: T) -> Self {
40 Self {
41 top: value.clone(),
42 right: value.clone(),
43 bottom: value.clone(),
44 left: value,
45 }
46 }
47
48 pub fn symmetric(horizontal: T, vertical: T) -> Self {
49 Self {
50 top: vertical.clone(),
51 right: horizontal.clone(),
52 bottom: vertical,
53 left: horizontal,
54 }
55 }
56}
57
58impl From<Edges4<Space>> for Edges4<MetricRef> {
59 fn from(value: Edges4<Space>) -> Self {
60 value.map(MetricRef::space)
61 }
62}
63
64impl From<Edges4<Px>> for Edges4<MetricRef> {
65 fn from(value: Edges4<Px>) -> Self {
66 value.map(MetricRef::Px)
67 }
68}
69
70impl From<Edges4<Space>> for Edges4<SignedMetricRef> {
71 fn from(value: Edges4<Space>) -> Self {
72 Edges4::<MetricRef>::from(value).pos()
73 }
74}
75
76impl From<Edges4<Px>> for Edges4<SignedMetricRef> {
77 fn from(value: Edges4<Px>) -> Self {
78 Edges4::<MetricRef>::from(value).pos()
79 }
80}
81
82impl Edges4<Space> {
83 pub fn pos(self) -> Edges4<SignedMetricRef> {
84 Edges4::<MetricRef>::from(self).pos()
85 }
86
87 #[allow(clippy::should_implement_trait)]
88 pub fn neg(self) -> Edges4<SignedMetricRef> {
89 Edges4::<MetricRef>::from(self).neg()
90 }
91}
92
93impl Edges4<Px> {
94 pub fn pos(self) -> Edges4<SignedMetricRef> {
95 Edges4::<MetricRef>::from(self).pos()
96 }
97
98 #[allow(clippy::should_implement_trait)]
99 pub fn neg(self) -> Edges4<SignedMetricRef> {
100 Edges4::<MetricRef>::from(self).neg()
101 }
102}
103
104impl Edges4<MetricRef> {
105 pub fn pos(self) -> Edges4<SignedMetricRef> {
106 self.map(SignedMetricRef::pos)
107 }
108
109 #[allow(clippy::should_implement_trait)]
110 pub fn neg(self) -> Edges4<SignedMetricRef> {
111 self.map(SignedMetricRef::neg)
112 }
113}
114
115#[derive(Debug, Clone)]
117pub enum MarginEdge {
118 Px(SignedMetricRef),
119 Auto,
120}
121
122impl MarginEdge {
123 pub fn auto() -> Self {
124 Self::Auto
125 }
126
127 pub fn px(metric: impl Into<SignedMetricRef>) -> Self {
128 Self::Px(metric.into())
129 }
130}
131
132impl From<SignedMetricRef> for MarginEdge {
133 fn from(value: SignedMetricRef) -> Self {
134 Self::Px(value)
135 }
136}
137
138impl From<MetricRef> for MarginEdge {
139 fn from(value: MetricRef) -> Self {
140 Self::Px(SignedMetricRef::pos(value))
141 }
142}
143
144impl From<Px> for MarginEdge {
145 fn from(value: Px) -> Self {
146 Self::from(MetricRef::Px(value))
147 }
148}
149
150impl From<Space> for MarginEdge {
151 fn from(value: Space) -> Self {
152 Self::from(MetricRef::space(value))
153 }
154}
155
156impl From<Edges4<Space>> for Edges4<MarginEdge> {
157 fn from(value: Edges4<Space>) -> Self {
158 value.map(MarginEdge::from)
159 }
160}
161
162impl From<Edges4<Px>> for Edges4<MarginEdge> {
163 fn from(value: Edges4<Px>) -> Self {
164 value.map(MarginEdge::from)
165 }
166}
167
168impl From<Edges4<MetricRef>> for Edges4<MarginEdge> {
169 fn from(value: Edges4<MetricRef>) -> Self {
170 value.map(MarginEdge::from)
171 }
172}
173
174impl From<Edges4<SignedMetricRef>> for Edges4<MarginEdge> {
175 fn from(value: Edges4<SignedMetricRef>) -> Self {
176 value.map(MarginEdge::from)
177 }
178}
179
180impl From<MarginEdge> for MarginEdgeRefinement {
181 fn from(value: MarginEdge) -> Self {
182 match value {
183 MarginEdge::Px(m) => MarginEdgeRefinement::Px(m),
184 MarginEdge::Auto => MarginEdgeRefinement::Auto,
185 }
186 }
187}