1use std::ops::Range;
2use std::rc::Rc;
3
4use std::cell::RefCell;
5
6use super::ImplToFromPaxAny;
7use super::Numeric;
8use super::PaxValue;
9use super::ToPaxValue;
10use crate::impl_to_pax_value;
11use crate::math::Space;
12use crate::math::Transform2;
13use crate::math::Vector2;
14use crate::properties::PropertyValue;
15use crate::Color;
16use crate::ColorChannel;
17use crate::Depth;
18use crate::Duration;
19use crate::Fill;
20use crate::GradientStop;
21use crate::LayoutRole;
22use crate::LightShape;
23use crate::LinearGradient;
24use crate::Material;
25use crate::MaterialParams;
26use crate::Opacity;
27use crate::PathElement;
28use crate::PathSmoothing;
29use crate::Percent;
30use crate::Property;
31use crate::RadialGradient;
32use crate::Rotation;
33use crate::SceneAmbientLight;
34use crate::SceneLight;
35use crate::SceneLighting;
36use crate::Size;
37use crate::Stroke;
38use crate::StrokeCap;
39use crate::StrokeJoin;
40use crate::Transform2D;
41use crate::UnitValue;
42use crate::Vector3;
43
44impl_to_pax_value!(bool, PaxValue::Bool);
46
47impl_to_pax_value!(u8, PaxValue::Numeric, Numeric::U8);
48impl_to_pax_value!(u16, PaxValue::Numeric, Numeric::U16);
49impl_to_pax_value!(u32, PaxValue::Numeric, Numeric::U32);
50impl_to_pax_value!(u64, PaxValue::Numeric, Numeric::U64);
51
52impl_to_pax_value!(i8, PaxValue::Numeric, Numeric::I8);
53impl_to_pax_value!(i16, PaxValue::Numeric, Numeric::I16);
54impl_to_pax_value!(i32, PaxValue::Numeric, Numeric::I32);
55impl_to_pax_value!(i64, PaxValue::Numeric, Numeric::I64);
56
57impl_to_pax_value!(f32, PaxValue::Numeric, Numeric::F32);
58impl_to_pax_value!(f64, PaxValue::Numeric, Numeric::F64);
59
60impl_to_pax_value!(isize, PaxValue::Numeric, Numeric::ISize);
61impl_to_pax_value!(usize, PaxValue::Numeric, Numeric::USize);
62
63impl ImplToFromPaxAny for () {}
65
66impl<F: Space, T: Space> ImplToFromPaxAny for Transform2<F, T> {}
68
69impl_to_pax_value!(String, PaxValue::String);
70
71impl_to_pax_value!(Numeric, PaxValue::Numeric);
73impl_to_pax_value!(Size, PaxValue::Size);
74impl_to_pax_value!(Rotation, PaxValue::Rotation);
75impl_to_pax_value!(Duration, PaxValue::Duration);
76impl_to_pax_value!(Percent, PaxValue::Percent);
77
78impl ToPaxValue for Depth {
79 fn to_pax_value(self) -> PaxValue {
80 PaxValue::Size(Size::Pixels(self.0))
81 }
82}
83
84impl ToPaxValue for LayoutRole {
85 fn to_pax_value(self) -> PaxValue {
86 let variant = match self {
87 LayoutRole::Default => "Default",
88 LayoutRole::Breakout => "Breakout",
89 };
90 PaxValue::Enum(Box::new((
91 "LayoutRole".to_string(),
92 variant.to_string(),
93 vec![],
94 )))
95 }
96}
97
98impl ToPaxValue for PathElement {
99 fn to_pax_value(self) -> PaxValue {
100 PaxValue::PathElement(Box::new(self))
101 }
102}
103
104impl ToPaxValue for Color {
105 fn to_pax_value(self) -> PaxValue {
106 PaxValue::Color(Box::new(self))
107 }
108}
109
110impl<T: ToPaxValue> ToPaxValue for Vec<T> {
112 fn to_pax_value(self) -> PaxValue {
113 PaxValue::Vec(
114 self.into_iter()
115 .map(|v| v.to_pax_value())
116 .collect::<Vec<_>>(),
117 )
118 }
119}
120
121impl<T: ToPaxValue> ToPaxValue for Option<T> {
122 fn to_pax_value(self) -> PaxValue {
123 match self {
124 Some(v) => PaxValue::Option(Box::new(Some(v.to_pax_value()))),
125 None => PaxValue::Option(Box::new(None)),
126 }
127 }
128}
129
130impl<T: ToPaxValue> ToPaxValue for Range<T> {
131 fn to_pax_value(self) -> PaxValue {
132 PaxValue::Range(
133 Box::new(self.start.to_pax_value()),
134 Box::new(self.end.to_pax_value()),
135 )
136 }
137}
138
139impl<T: ToPaxValue + Clone> ToPaxValue for Rc<RefCell<T>> {
140 fn to_pax_value(self) -> PaxValue {
141 crate::borrow!(self).clone().to_pax_value()
142 }
143}
144
145impl ToPaxValue for PaxValue {
146 fn to_pax_value(self) -> PaxValue {
147 self
148 }
149}
150
151impl<T: ToPaxValue + PropertyValue> ToPaxValue for Property<T> {
152 fn to_pax_value(self) -> PaxValue {
153 self.get().to_pax_value()
154 }
155}
156
157impl ToPaxValue for Fill {
158 fn to_pax_value(self) -> PaxValue {
159 match self {
160 Fill::Solid(color) => PaxValue::Enum(Box::new((
161 "Fill".to_string(),
162 "Solid".to_string(),
163 vec![color.to_pax_value()],
164 ))),
165 Fill::LinearGradient(gradient) => PaxValue::Enum(Box::new((
166 "Fill".to_string(),
167 "LinearGradient".to_string(),
168 vec![gradient.to_pax_value()],
169 ))),
170 Fill::RadialGradient(gradient) => PaxValue::Enum(Box::new((
171 "Fill".to_string(),
172 "RadialGradient".to_string(),
173 vec![gradient.to_pax_value()],
174 ))),
175 }
176 }
177}
178
179impl ToPaxValue for ColorChannel {
180 fn to_pax_value(self) -> PaxValue {
181 match self {
182 ColorChannel::Rotation(rot) => PaxValue::Enum(Box::new((
183 "ColorChannel".to_string(),
184 "Rotation".to_string(),
185 vec![rot.to_pax_value()],
186 ))),
187 ColorChannel::Percent(perc) => PaxValue::Enum(Box::new((
188 "ColorChannel".to_string(),
189 "Percent".to_string(),
190 vec![perc.to_pax_value()],
191 ))),
192 ColorChannel::Integer(num) => PaxValue::Enum(Box::new((
193 "ColorChannel".to_string(),
194 "Integer".to_string(),
195 vec![num.to_pax_value()],
196 ))),
197 }
198 }
199}
200
201impl ToPaxValue for Opacity {
202 fn to_pax_value(self) -> PaxValue {
203 match self {
204 Opacity::Alpha(value) => PaxValue::Enum(Box::new((
205 "Opacity".to_string(),
206 "Alpha".to_string(),
207 vec![value.to_pax_value()],
208 ))),
209 Opacity::Percent(value) => PaxValue::Enum(Box::new((
210 "Opacity".to_string(),
211 "Percent".to_string(),
212 vec![value.to_pax_value()],
213 ))),
214 }
215 }
216}
217
218impl ToPaxValue for UnitValue {
219 fn to_pax_value(self) -> PaxValue {
220 match self {
221 UnitValue::Unitless(value) => PaxValue::Enum(Box::new((
222 "UnitValue".to_string(),
223 "Unitless".to_string(),
224 vec![value.to_pax_value()],
225 ))),
226 UnitValue::Percent(value) => PaxValue::Enum(Box::new((
227 "UnitValue".to_string(),
228 "Percent".to_string(),
229 vec![value.to_pax_value()],
230 ))),
231 }
232 }
233}
234
235impl ToPaxValue for Stroke {
236 fn to_pax_value(self) -> PaxValue {
237 PaxValue::Object(
238 vec![
239 ("color".to_string(), self.color.get().to_pax_value()),
240 ("width".to_string(), self.width.to_pax_value()),
241 ("cap".to_string(), self.cap.get().to_pax_value()),
242 ("join".to_string(), self.join.get().to_pax_value()),
243 ]
244 .into_iter()
245 .collect(),
246 )
247 }
248}
249
250impl ToPaxValue for StrokeCap {
251 fn to_pax_value(self) -> PaxValue {
252 let variant = match self {
253 StrokeCap::Butt => "Butt",
254 StrokeCap::Round => "Round",
255 StrokeCap::Square => "Square",
256 };
257 PaxValue::Enum(Box::new((
258 "StrokeCap".to_string(),
259 variant.to_string(),
260 vec![],
261 )))
262 }
263}
264
265impl ToPaxValue for PathSmoothing {
266 fn to_pax_value(self) -> PaxValue {
267 let variant = match self {
268 PathSmoothing::None => "None",
269 PathSmoothing::Light => "Light",
270 PathSmoothing::Strong => "Strong",
271 };
272 PaxValue::Enum(Box::new((
273 "PathSmoothing".to_string(),
274 variant.to_string(),
275 vec![],
276 )))
277 }
278}
279
280impl ToPaxValue for StrokeJoin {
281 fn to_pax_value(self) -> PaxValue {
282 let variant = match self {
283 StrokeJoin::Miter => "Miter",
284 StrokeJoin::Round => "Round",
285 StrokeJoin::Bevel => "Bevel",
286 };
287 PaxValue::Enum(Box::new((
288 "StrokeJoin".to_string(),
289 variant.to_string(),
290 vec![],
291 )))
292 }
293}
294
295impl ToPaxValue for LightShape {
296 fn to_pax_value(self) -> PaxValue {
297 let variant = match self {
298 LightShape::Point => "Point",
299 LightShape::Directional => "Directional",
300 };
301 PaxValue::Enum(Box::new((
302 "LightShape".to_string(),
303 variant.to_string(),
304 vec![],
305 )))
306 }
307}
308
309impl ToPaxValue for Vector3 {
310 fn to_pax_value(self) -> PaxValue {
311 PaxValue::Object(
312 vec![
313 ("x".to_string(), self.x.to_pax_value()),
314 ("y".to_string(), self.y.to_pax_value()),
315 ("z".to_string(), self.z.to_pax_value()),
316 ]
317 .into_iter()
318 .collect(),
319 )
320 }
321}
322
323impl ToPaxValue for MaterialParams {
324 fn to_pax_value(self) -> PaxValue {
325 PaxValue::Object(
326 vec![
327 ("ambient".to_string(), self.ambient.get().to_pax_value()),
328 ("diffuse".to_string(), self.diffuse.get().to_pax_value()),
329 ("specular".to_string(), self.specular.get().to_pax_value()),
330 ("roughness".to_string(), self.roughness.get().to_pax_value()),
331 ("metallic".to_string(), self.metallic.get().to_pax_value()),
332 ("emissive".to_string(), self.emissive.get().to_pax_value()),
333 (
334 "emissive_intensity".to_string(),
335 self.emissive_intensity.get().to_pax_value(),
336 ),
337 ]
338 .into_iter()
339 .collect(),
340 )
341 }
342}
343
344impl ToPaxValue for Material {
345 fn to_pax_value(self) -> PaxValue {
346 match self {
347 Material::Lit(params) => PaxValue::Enum(Box::new((
348 "Material".to_string(),
349 "Lit".to_string(),
350 vec![params.to_pax_value()],
351 ))),
352 Material::Unlit => PaxValue::Enum(Box::new((
353 "Material".to_string(),
354 "Unlit".to_string(),
355 vec![],
356 ))),
357 }
358 }
359}
360
361impl ToPaxValue for SceneAmbientLight {
362 fn to_pax_value(self) -> PaxValue {
363 PaxValue::Object(
364 vec![
365 ("color".to_string(), self.color.to_pax_value()),
366 ("intensity".to_string(), self.intensity.to_pax_value()),
367 ]
368 .into_iter()
369 .collect(),
370 )
371 }
372}
373
374impl ToPaxValue for SceneLight {
375 fn to_pax_value(self) -> PaxValue {
376 PaxValue::Object(
377 vec![
378 ("shape".to_string(), self.shape.to_pax_value()),
379 ("position".to_string(), self.position.to_pax_value()),
380 ("direction".to_string(), self.direction.to_pax_value()),
381 ("color".to_string(), self.color.to_pax_value()),
382 ("intensity".to_string(), self.intensity.to_pax_value()),
383 ("radius".to_string(), self.radius.to_pax_value()),
384 ("enabled".to_string(), self.enabled.to_pax_value()),
385 ]
386 .into_iter()
387 .collect(),
388 )
389 }
390}
391
392impl ToPaxValue for SceneLighting {
393 fn to_pax_value(self) -> PaxValue {
394 PaxValue::Object(
395 vec![
396 ("active".to_string(), self.active.to_pax_value()),
397 (
398 "ambient_is_authored".to_string(),
399 self.ambient_is_authored.to_pax_value(),
400 ),
401 ("ambient".to_string(), self.ambient.to_pax_value()),
402 ("lights".to_string(), self.lights.to_pax_value()),
403 ]
404 .into_iter()
405 .collect(),
406 )
407 }
408}
409
410impl ToPaxValue for GradientStop {
411 fn to_pax_value(self) -> PaxValue {
412 PaxValue::Object(
413 vec![
414 ("position".to_string(), self.position.to_pax_value()),
415 ("color".to_string(), self.color.to_pax_value()),
416 ]
417 .into_iter()
418 .collect(),
419 )
420 }
421}
422
423impl ToPaxValue for LinearGradient {
424 fn to_pax_value(self) -> PaxValue {
425 PaxValue::Object(
426 vec![
427 (
428 "start".to_string(),
429 PaxValue::Vec(vec![
430 self.start.0.to_pax_value(),
431 self.start.1.to_pax_value(),
432 ]),
433 ),
434 (
435 "end".to_string(),
436 PaxValue::Vec(vec![self.end.0.to_pax_value(), self.end.1.to_pax_value()]),
437 ),
438 ("stops".to_string(), self.stops.to_pax_value()),
439 ]
440 .into_iter()
441 .collect(),
442 )
443 }
444}
445
446impl ToPaxValue for RadialGradient {
447 fn to_pax_value(self) -> PaxValue {
448 PaxValue::Object(
449 vec![
450 (
451 "start".to_string(),
452 PaxValue::Vec(vec![
453 self.start.0.to_pax_value(),
454 self.start.1.to_pax_value(),
455 ]),
456 ),
457 (
458 "end".to_string(),
459 PaxValue::Vec(vec![self.end.0.to_pax_value(), self.end.1.to_pax_value()]),
460 ),
461 ("radius".to_string(), self.radius.to_pax_value()),
462 ("stops".to_string(), self.stops.to_pax_value()),
463 ]
464 .into_iter()
465 .collect(),
466 )
467 }
468}
469
470impl ToPaxValue for Transform2D {
471 fn to_pax_value(self) -> PaxValue {
472 PaxValue::Object(
473 vec![
474 (
475 "previous".to_string(),
476 self.previous
477 .map(|p| p.to_pax_value())
478 .unwrap_or(PaxValue::Option(Box::new(None))),
479 ),
480 (
481 "rotate".to_string(),
482 self.rotate
483 .map(|r| r.to_pax_value())
484 .unwrap_or(PaxValue::Option(Box::new(None))),
485 ),
486 (
487 "translate".to_string(),
488 self.translate
489 .map(|t| PaxValue::Option(Box::new(Some(t.to_vec().to_pax_value()))))
490 .unwrap_or(PaxValue::Option(Box::new(None))),
491 ),
492 (
493 "anchor".to_string(),
494 self.anchor
495 .map(|a| PaxValue::Option(Box::new(Some(a.to_vec().to_pax_value()))))
496 .unwrap_or(PaxValue::Option(Box::new(None))),
497 ),
498 (
499 "scale".to_string(),
500 self.scale
501 .map(|s| PaxValue::Option(Box::new(Some(s.to_vec().to_pax_value()))))
502 .unwrap_or(PaxValue::Option(Box::new(None))),
503 ),
504 (
505 "skew".to_string(),
506 self.skew
507 .map(|s| PaxValue::Option(Box::new(Some(s.to_vec().to_pax_value()))))
508 .unwrap_or(PaxValue::Option(Box::new(None))),
509 ),
510 ]
511 .into_iter()
512 .collect(),
513 )
514 }
515}
516
517impl ToPaxValue for Transform2 {
518 fn to_pax_value(self) -> PaxValue {
519 PaxValue::Object(
520 vec![(
521 "m".to_string(),
522 PaxValue::Vec(self.m.iter().map(|v| v.to_pax_value()).collect::<Vec<_>>()),
523 )]
524 .into_iter()
525 .collect(),
526 )
527 }
528}
529
530impl ToPaxValue for Vector2 {
531 fn to_pax_value(self) -> PaxValue {
532 PaxValue::Object(
533 vec![
534 ("x".to_string(), self.x.to_pax_value()),
535 ("y".to_string(), self.y.to_pax_value()),
536 ]
537 .into_iter()
538 .collect(),
539 )
540 }
541}