aura_anim_iced/
property.rs1mod kind;
4mod spec;
5#[cfg(test)]
6mod tests;
7mod value;
8
9pub use kind::{Color, PropertyValueKind, Rectangle, Scalar, Shadow, Size, Transform, Vector2};
10pub use spec::{PropertySpec, RawPropertySpec};
11pub use value::{PropertyValue, TransformValue};
12
13pub const OPACITY: PropertySpec<Scalar> =
15 PropertySpec::new(PropertyKey::new("aura", "opacity"), 10);
16pub const TRANSFORM: PropertySpec<Transform> =
18 PropertySpec::new(PropertyKey::new("aura", "transform"), 18);
19pub const TRANSLATE: PropertySpec<Vector2> =
21 PropertySpec::new(PropertyKey::new("aura", "translate"), 19);
22pub const SCALE: PropertySpec<Scalar> = PropertySpec::new(PropertyKey::new("aura", "scale"), 20);
24pub const ROTATE: PropertySpec<Scalar> = PropertySpec::new(PropertyKey::new("aura", "rotate"), 21);
26pub const WIDTH: PropertySpec<Scalar> = PropertySpec::new(PropertyKey::new("aura", "width"), 30);
28pub const HEIGHT: PropertySpec<Scalar> = PropertySpec::new(PropertyKey::new("aura", "height"), 31);
30pub const PADDING: PropertySpec<Scalar> =
32 PropertySpec::new(PropertyKey::new("aura", "padding"), 40);
33pub const RADIUS: PropertySpec<Scalar> = PropertySpec::new(PropertyKey::new("aura", "radius"), 50);
35pub const BACKGROUND: PropertySpec<Color> =
37 PropertySpec::new(PropertyKey::new("aura", "background"), 60);
38pub const BORDER_COLOR: PropertySpec<Color> =
40 PropertySpec::new(PropertyKey::new("aura", "border-color"), 70);
41pub const TEXT_COLOR: PropertySpec<Color> =
43 PropertySpec::new(PropertyKey::new("aura", "text-color"), 80);
44pub const SHADOW: PropertySpec<Shadow> = PropertySpec::new(PropertyKey::new("aura", "shadow"), 90);
46
47#[derive(Debug, Clone, PartialEq)]
71pub struct PropertySnapshot {
72 entries: Vec<PropertyEntry>,
73}
74
75impl<K: PropertyValueKind> From<Vec<(PropertySpec<K>, K::Inner)>> for PropertySnapshot {
76 fn from(value: Vec<(PropertySpec<K>, K::Inner)>) -> Self {
77 let mut s = Self {
78 entries: value
79 .into_iter()
80 .map(|(spec, value)| PropertyEntry::new(spec, value))
81 .collect(),
82 };
83 s.sort_by_composition_key();
84
85 s
86 }
87}
88
89impl<K: PropertyValueKind> From<(PropertySpec<K>, K::Inner)> for PropertySnapshot {
90 fn from(value: (PropertySpec<K>, K::Inner)) -> Self {
91 Self {
92 entries: vec![PropertyEntry::new(value.0, value.1)],
93 }
94 }
95}
96
97impl From<Vec<PropertyEntry>> for PropertySnapshot {
98 fn from(entries: Vec<PropertyEntry>) -> Self {
99 let mut s = Self { entries };
100 s.sort_by_composition_key();
101
102 s
103 }
104}
105
106impl PropertySnapshot {
107 #[must_use]
109 pub const fn new() -> Self {
110 Self {
111 entries: Vec::new(),
112 }
113 }
114
115 #[must_use]
117 pub const fn is_empty(&self) -> bool {
118 self.entries.is_empty()
119 }
120
121 #[must_use]
123 pub fn entries(&self) -> &[PropertyEntry] {
124 &self.entries
125 }
126
127 pub(crate) fn sort_by_composition_key(&mut self) {
128 self.entries
129 .sort_by_key(|entry| entry.spec.composition_order());
130 }
131
132 pub fn merge(&mut self, other: Self) {
137 self.merge_unsorted(other);
138 self.sort_by_composition_key();
139 }
140
141 #[must_use]
143 pub fn find_property(&self, property: &RawPropertySpec) -> Option<&PropertyEntry> {
144 self.entries.iter().find(|entry| entry.spec == *property)
145 }
146
147 pub(crate) fn push(&mut self, entry: PropertyEntry) {
148 self.entries.push(entry);
149 }
150
151 pub(crate) fn clear(&mut self) {
152 self.entries.clear();
153 }
154
155 pub(crate) fn replace_from(&mut self, other: &Self) {
156 self.entries.clear();
157 self.entries.extend_from_slice(other.entries());
158 }
159
160 pub(crate) fn with_capacity(capacity: usize) -> Self {
161 Self {
162 entries: Vec::with_capacity(capacity),
163 }
164 }
165
166 pub(crate) fn merge_unsorted(&mut self, other: Self) {
167 other.entries.into_iter().for_each(|snapshot| {
168 if let Some(entry) = self.find_property_mut(&snapshot.spec) {
169 entry.value = snapshot.value;
170 } else {
171 self.entries.push(snapshot);
172 }
173 });
174 }
175
176 pub(crate) fn merge_entries_unsorted(&mut self, entries: &[PropertyEntry]) {
177 for snapshot in entries {
178 if let Some(entry) = self.find_property_mut(snapshot.spec()) {
179 entry.value = *snapshot.value();
180 } else {
181 self.entries.push(*snapshot);
182 }
183 }
184 }
185
186 fn find_property_mut(&mut self, property: &RawPropertySpec) -> Option<&mut PropertyEntry> {
187 self.entries
188 .iter_mut()
189 .find(|entry| entry.spec == *property)
190 }
191}
192
193impl Default for PropertySnapshot {
194 fn default() -> Self {
195 Self::new()
196 }
197}
198
199#[derive(Debug, Clone, Copy, PartialEq)]
201pub struct PropertyEntry {
202 spec: RawPropertySpec,
203 value: PropertyValue,
204}
205
206impl PropertyEntry {
207 #[must_use]
209 pub fn new<K: PropertyValueKind>(spec: PropertySpec<K>, value: K::Inner) -> Self {
210 Self {
211 spec: spec.raw(),
212 value: K::wrap(value),
213 }
214 }
215
216 #[must_use]
218 pub fn spec(&self) -> &RawPropertySpec {
219 &self.spec
220 }
221
222 #[must_use]
224 pub fn value(&self) -> &PropertyValue {
225 &self.value
226 }
227
228 pub(crate) fn new_unchecked(spec: RawPropertySpec, value: PropertyValue) -> Self {
229 Self { spec, value }
230 }
231}
232
233#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
249pub struct PropertyKey {
250 namespace: &'static str,
251 name: &'static str,
252}
253
254impl PropertyKey {
255 #[must_use]
257 pub const fn new(namespace: &'static str, name: &'static str) -> Self {
258 Self { namespace, name }
259 }
260
261 #[must_use]
263 pub const fn namespace(&self) -> &'static str {
264 self.namespace
265 }
266
267 #[must_use]
269 pub const fn name(&self) -> &'static str {
270 self.name
271 }
272}