lottie_data/
model.rs

1use serde::{de::SeqAccess, de::DeserializeOwned, Deserialize, Deserializer, Serialize};
2use std::fmt;
3
4#[derive(Debug, Serialize, Deserialize, Clone)]
5pub struct LottieJson {
6    pub v: Option<String>,
7    pub ip: f32,
8    pub op: f32,
9    pub fr: f32,
10    pub w: u32,
11    pub h: u32,
12    pub layers: Vec<Layer>,
13    #[serde(default)]
14    pub assets: Vec<Asset>,
15}
16
17#[derive(Debug, Serialize, Deserialize, Clone)]
18pub struct Layer {
19    // Common
20    #[serde(default)]
21    pub ty: u8, // 0..5
22    #[serde(default)]
23    pub ind: Option<u32>,
24    #[serde(default)]
25    pub parent: Option<u32>,
26    #[serde(default)]
27    pub nm: Option<String>,
28    #[serde(default)]
29    pub ip: f32,
30    #[serde(default)]
31    pub op: f32,
32    #[serde(default = "default_one")]
33    pub st: f32,
34    #[serde(default)]
35    pub ks: Transform,
36    #[serde(default)]
37    pub ao: Option<u32>,
38    #[serde(default)]
39    pub tm: Option<Property<f32>>,
40    #[serde(default)]
41    pub ddd: Option<u8>, // 3D Layer Flag (0=2D, 1=3D)
42    #[serde(default)]
43    pub pe: Option<Property<f32>>, // Perspective
44
45    #[serde(default, rename = "masksProperties")]
46    pub masks_properties: Option<Vec<MaskProperties>>,
47    #[serde(default)]
48    pub tt: Option<u8>,
49    #[serde(default)]
50    pub ef: Option<Vec<Effect>>,
51    #[serde(default)]
52    pub sy: Option<Vec<LayerStyle>>,
53
54    // Type specific (flattened manually as optional fields)
55    #[serde(default, rename = "refId")]
56    pub ref_id: Option<String>, // PreComp, Image
57    #[serde(default)]
58    pub w: Option<u32>, // PreComp
59    #[serde(default)]
60    pub h: Option<u32>, // PreComp
61    #[serde(default, rename = "sc")]
62    pub color: Option<String>, // Solid color
63    #[serde(default)]
64    pub sw: Option<u32>, // Solid width
65    #[serde(default)]
66    pub sh: Option<u32>, // Solid height
67    #[serde(default)]
68    pub shapes: Option<Vec<Shape>>, // Shape Layer
69    #[serde(default)]
70    pub t: Option<TextData>, // Text Layer
71}
72
73fn default_one() -> f32 {
74    1.0
75}
76
77#[derive(Debug, Serialize, Deserialize, Clone)]
78pub struct MaskProperties {
79    #[serde(default)]
80    pub inv: bool,
81    #[serde(default)]
82    pub mode: Option<String>,
83    pub pt: Property<BezierPath>,
84    pub o: Property<f32>,
85    #[serde(default)]
86    pub x: Property<f32>,
87    #[serde(default)]
88    pub nm: Option<String>,
89}
90
91#[derive(Debug, Serialize, Deserialize, Clone)]
92pub struct Effect {
93    #[serde(default)]
94    pub ty: Option<u8>,
95    #[serde(default)]
96    pub nm: Option<String>,
97    #[serde(default)]
98    pub ix: Option<u32>,
99    #[serde(default)]
100    pub en: Option<u8>,
101    #[serde(default)]
102    pub ef: Option<Vec<EffectValue>>,
103}
104
105#[derive(Debug, Serialize, Deserialize, Clone)]
106pub struct EffectValue {
107    #[serde(default)]
108    pub ty: Option<u8>,
109    #[serde(default)]
110    pub nm: Option<String>,
111    #[serde(default)]
112    pub ix: Option<u32>,
113    #[serde(default, deserialize_with = "deserialize_effect_value_property")]
114    pub v: Option<Property<serde_json::Value>>,
115}
116
117fn deserialize_effect_value_property<'de, D>(
118    deserializer: D,
119) -> Result<Option<Property<serde_json::Value>>, D::Error>
120where
121    D: Deserializer<'de>,
122{
123    let mut v = serde_json::Value::deserialize(deserializer)?;
124    if v.is_null() {
125        return Ok(None);
126    }
127
128    // Unwrap single-element array
129    if let serde_json::Value::Array(arr) = &v {
130        if arr.len() == 1 {
131            v = arr[0].clone();
132        }
133    }
134
135    if v.is_object() && v.get("k").is_some() {
136        if let Ok(p) = serde_json::from_value::<Property<serde_json::Value>>(v.clone()) {
137            return Ok(Some(p));
138        }
139    }
140
141    // Fallback: Treat as static value
142    Ok(Some(Property {
143        k: Value::Static(v),
144        a: 0,
145        ix: None,
146        x: None,
147    }))
148}
149
150#[derive(Debug, Serialize, Deserialize, Clone)]
151pub struct LayerStyle {
152    #[serde(default)]
153    pub ty: Option<u8>,
154    #[serde(default)]
155    pub nm: Option<String>,
156    #[serde(default)]
157    pub c: Property<Vec<f32>>, // Color
158    #[serde(default)]
159    pub o: Property<f32>,      // Opacity
160    #[serde(default)]
161    pub a: Property<f32>,      // Angle
162    #[serde(default)]
163    pub d: Property<f32>,      // Distance
164    #[serde(default)]
165    pub s: Property<f32>,      // Size / Blur
166    #[serde(default)]
167    pub ch: Property<f32>,     // Choke / Spread / Range
168    #[serde(default)]
169    pub bm: Option<Property<f32>>, // Blend Mode
170}
171
172// Shapes
173
174#[derive(Debug, Serialize, Deserialize, Clone)]
175#[serde(tag = "ty")]
176pub enum Shape {
177    #[serde(rename = "gr")]
178    Group(GroupShape),
179    #[serde(rename = "rc")]
180    Rect(RectShape),
181    #[serde(rename = "el")]
182    Ellipse(EllipseShape),
183    #[serde(rename = "fl")]
184    Fill(FillShape),
185    #[serde(rename = "st")]
186    Stroke(StrokeShape),
187    #[serde(rename = "gf")]
188    GradientFill(GradientFillShape),
189    #[serde(rename = "gs")]
190    GradientStroke(GradientStrokeShape),
191    #[serde(rename = "tr")]
192    Transform(TransformShape),
193    #[serde(rename = "sh")]
194    Path(PathShape),
195    #[serde(rename = "tm")]
196    Trim(TrimShape),
197    #[serde(rename = "sr")]
198    Polystar(PolystarShape),
199    #[serde(rename = "rp")]
200    Repeater(RepeaterShape),
201    #[serde(rename = "rd")]
202    RoundCorners(RoundCornersShape),
203    #[serde(rename = "zz")]
204    ZigZag(ZigZagShape),
205    #[serde(rename = "pb")]
206    PuckerBloat(PuckerBloatShape),
207    #[serde(rename = "tw")]
208    Twist(TwistShape),
209    #[serde(rename = "op")]
210    OffsetPath(OffsetPathShape),
211    #[serde(rename = "wgl")]
212    WigglePath(WigglePathShape),
213    #[serde(rename = "mm")]
214    MergePaths(MergePathsShape),
215    #[serde(other)]
216    Unknown,
217}
218
219#[derive(Debug, Serialize, Deserialize, Clone)]
220pub struct MergePathsShape {
221    #[serde(default)]
222    pub nm: Option<String>,
223    #[serde(default)]
224    pub mm: u8,
225}
226
227#[derive(Debug, Serialize, Deserialize, Clone)]
228pub struct ZigZagShape {
229    #[serde(default)]
230    pub nm: Option<String>,
231    pub r: Property<f32>,
232    pub s: Property<f32>,
233    #[serde(default)]
234    pub pt: Property<f32>,
235}
236
237#[derive(Debug, Serialize, Deserialize, Clone)]
238pub struct PuckerBloatShape {
239    #[serde(default)]
240    pub nm: Option<String>,
241    pub a: Property<f32>,
242}
243
244#[derive(Debug, Serialize, Deserialize, Clone)]
245pub struct TwistShape {
246    #[serde(default)]
247    pub nm: Option<String>,
248    pub a: Property<f32>,
249    pub c: Property<Vec2>,
250}
251
252#[derive(Debug, Serialize, Deserialize, Clone)]
253pub struct OffsetPathShape {
254    #[serde(default)]
255    pub nm: Option<String>,
256    pub a: Property<f32>,
257    #[serde(default)]
258    pub lj: u8,
259    #[serde(default)]
260    pub ml: Option<f32>,
261}
262
263#[derive(Debug, Serialize, Deserialize, Clone)]
264pub struct WigglePathShape {
265    #[serde(default)]
266    pub nm: Option<String>,
267    pub s: Property<f32>,
268    pub w: Property<f32>,
269    #[serde(default)]
270    pub r: Property<f32>,
271    #[serde(default)]
272    pub sh: Property<f32>,
273}
274
275#[derive(Debug, Serialize, Deserialize, Clone)]
276pub struct PolystarShape {
277    #[serde(default)]
278    pub nm: Option<String>,
279    pub p: PositionProperty,
280    pub or: Property<f32>,
281    #[serde(default)]
282    pub os: Property<f32>,
283    pub r: Property<f32>,
284    pub pt: Property<f32>,
285    #[serde(default)]
286    pub sy: u8,
287    #[serde(default)]
288    pub ir: Option<Property<f32>>,
289    #[serde(default)]
290    pub is: Option<Property<f32>>,
291}
292
293#[derive(Debug, Serialize, Deserialize, Clone)]
294pub struct RepeaterShape {
295    #[serde(default)]
296    pub nm: Option<String>,
297    pub c: Property<f32>,
298    pub o: Property<f32>,
299    #[serde(default)]
300    pub m: u8,
301    pub tr: RepeaterTransform,
302}
303
304#[derive(Debug, Serialize, Deserialize, Clone)]
305pub struct RepeaterTransform {
306    #[serde(flatten)]
307    pub t: Transform,
308    #[serde(default)]
309    pub so: Property<f32>,
310    #[serde(default)]
311    pub eo: Property<f32>,
312}
313
314#[derive(Debug, Serialize, Deserialize, Clone)]
315pub struct RoundCornersShape {
316    #[serde(default)]
317    pub nm: Option<String>,
318    pub r: Property<f32>,
319}
320
321#[derive(Debug, Serialize, Deserialize, Clone)]
322pub struct GroupShape {
323    #[serde(default)]
324    pub nm: Option<String>,
325    pub it: Vec<Shape>,
326}
327
328#[derive(Debug, Serialize, Deserialize, Clone)]
329pub struct RectShape {
330    #[serde(default)]
331    pub nm: Option<String>,
332    pub s: Property<Vec2>,
333    pub p: Property<Vec2>,
334    pub r: Property<f32>,
335}
336
337#[derive(Debug, Serialize, Deserialize, Clone)]
338pub struct EllipseShape {
339    #[serde(default)]
340    pub nm: Option<String>,
341    pub s: Property<Vec2>,
342    pub p: Property<Vec2>,
343}
344
345#[derive(Debug, Serialize, Deserialize, Clone)]
346pub struct FillShape {
347    #[serde(default)]
348    pub nm: Option<String>,
349    pub c: Property<Vec4>,
350    pub o: Property<f32>,
351    #[serde(default)]
352    pub r: Option<u8>,
353}
354
355#[derive(Debug, Serialize, Deserialize, Clone)]
356pub struct StrokeShape {
357    #[serde(default)]
358    pub nm: Option<String>,
359    pub c: Property<Vec4>,
360    pub w: Property<f32>,
361    pub o: Property<f32>,
362    #[serde(default)]
363    pub lc: u8,
364    #[serde(default)]
365    pub lj: u8,
366    #[serde(default)]
367    pub ml: Option<f32>,
368    #[serde(default)]
369    pub d: Vec<DashProperty>,
370}
371
372#[derive(Debug, Serialize, Deserialize, Clone)]
373pub struct DashProperty {
374    pub n: Option<String>,
375    pub v: Property<f32>,
376}
377
378#[derive(Debug, Serialize, Deserialize, Clone)]
379pub struct GradientFillShape {
380    #[serde(default)]
381    pub nm: Option<String>,
382    pub o: Property<f32>,
383    pub s: Property<Vec2>,
384    pub e: Property<Vec2>,
385    pub t: u8,
386    pub g: GradientColors,
387}
388
389#[derive(Debug, Serialize, Deserialize, Clone)]
390pub struct GradientStrokeShape {
391    #[serde(default)]
392    pub nm: Option<String>,
393    pub o: Property<f32>,
394    pub w: Property<f32>,
395    pub s: Property<Vec2>,
396    pub e: Property<Vec2>,
397    pub t: u8,
398    pub g: GradientColors,
399    #[serde(default)]
400    pub lc: u8,
401    #[serde(default)]
402    pub lj: u8,
403    #[serde(default)]
404    pub ml: Option<f32>,
405    #[serde(default)]
406    pub d: Vec<DashProperty>,
407}
408
409#[derive(Debug, Serialize, Deserialize, Clone, Default)]
410pub struct GradientColors {
411    pub p: u32,
412    pub k: Property<Vec<f32>>,
413}
414
415#[derive(Debug, Serialize, Deserialize, Clone)]
416pub struct PathShape {
417    #[serde(default)]
418    pub nm: Option<String>,
419    pub ks: Property<BezierPath>,
420}
421
422#[derive(Debug, Serialize, Deserialize, Clone)]
423pub struct TrimShape {
424    #[serde(default)]
425    pub nm: Option<String>,
426    pub s: Property<f32>,
427    pub e: Property<f32>,
428    pub o: Property<f32>,
429    #[serde(default)]
430    pub m: u8,
431}
432
433#[derive(Debug, Serialize, Deserialize, Clone)]
434pub struct TransformShape {
435    #[serde(flatten)]
436    pub t: Transform,
437}
438
439#[derive(Debug, Serialize, Deserialize, Clone, Default)]
440pub struct Transform {
441    #[serde(default)]
442    pub a: Property<Vec3DefaultZero>, // Anchor: Vec3, default z=0
443    #[serde(default)]
444    pub p: PositionProperty,          // Position: Vec3, default z=0
445    #[serde(default)]
446    pub s: Property<Vec3Scale>,       // Scale: Vec3, default z=100
447    #[serde(default, alias = "r")]
448    pub rz: Property<f32>,            // Rotation Z
449    #[serde(default)]
450    pub rx: Option<Property<f32>>,    // Rotation X
451    #[serde(default)]
452    pub ry: Option<Property<f32>>,    // Rotation Y
453    #[serde(default)]
454    pub or: Option<Property<Vec3DefaultZero>>, // Orientation
455    #[serde(default)]
456    pub o: Property<f32>,             // Opacity
457}
458
459#[derive(Debug, Serialize, Deserialize, Clone)]
460#[serde(untagged)]
461pub enum PositionProperty {
462    Unified(Property<Vec3DefaultZero>),
463    Split {
464        x: Property<f32>,
465        y: Property<f32>,
466        #[serde(default)]
467        z: Option<Property<f32>>,
468    },
469}
470
471impl Default for PositionProperty {
472    fn default() -> Self {
473        PositionProperty::Unified(Property::default())
474    }
475}
476
477#[derive(Debug, Serialize, Deserialize, Clone)]
478pub struct Property<T> {
479    #[serde(default)]
480    pub a: u8,
481    #[serde(default)]
482    #[serde(bound(deserialize = "T: DeserializeOwned"))]
483    pub k: Value<T>,
484    #[serde(default)]
485    pub ix: Option<u32>,
486    #[serde(default)]
487    pub x: Option<String>,
488}
489
490impl<T> Default for Property<T> {
491    fn default() -> Self {
492        Property {
493            a: 0,
494            k: Value::Default,
495            ix: None,
496            x: None,
497        }
498    }
499}
500
501#[derive(Debug, Serialize, Clone)]
502pub enum Value<T> {
503    Default,
504    Static(T),
505    Animated(Vec<Keyframe<T>>),
506}
507
508impl<'de, T: DeserializeOwned> Deserialize<'de> for Value<T> {
509    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
510    where
511        D: Deserializer<'de>,
512    {
513        let v = serde_json::Value::deserialize(deserializer)?;
514
515        if v.is_null() {
516            return Ok(Value::Default);
517        }
518
519        if let Ok(keyframes) = serde_json::from_value::<Vec<Keyframe<T>>>(v.clone()) {
520            return Ok(Value::Animated(keyframes));
521        }
522
523        if let Ok(val) = serde_json::from_value::<T>(v.clone()) {
524            return Ok(Value::Static(val));
525        }
526
527        if let Ok(vec) = serde_json::from_value::<Vec<T>>(v) {
528            if let Some(first) = vec.into_iter().next() {
529                return Ok(Value::Static(first));
530            }
531        }
532
533        Ok(Value::Default)
534    }
535}
536
537impl<T> Default for Value<T> {
538    fn default() -> Self {
539        Value::Default
540    }
541}
542
543#[derive(Debug, Serialize, Deserialize, Clone)]
544#[serde(bound(deserialize = "T: DeserializeOwned"))]
545pub struct Keyframe<T> {
546    pub t: f32,
547    #[serde(default, deserialize_with = "deserialize_keyframe_value")]
548    pub s: Option<T>,
549    #[serde(default, deserialize_with = "deserialize_keyframe_value")]
550    pub e: Option<T>,
551    pub i: Option<Vec2>,
552    pub o: Option<Vec2>,
553    pub to: Option<Vec<f32>>,
554    pub ti: Option<Vec<f32>>,
555    pub h: Option<u8>,
556}
557
558fn deserialize_keyframe_value<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
559where
560    D: Deserializer<'de>,
561    T: DeserializeOwned,
562{
563    let v = serde_json::Value::deserialize(deserializer)?;
564    if v.is_null() {
565        return Ok(None);
566    }
567
568    if let Ok(val) = serde_json::from_value(v.clone()) {
569        return Ok(Some(val));
570    }
571
572    if let Ok(vec) = serde_json::from_value::<Vec<T>>(v) {
573        if let Some(first) = vec.into_iter().next() {
574            return Ok(Some(first));
575        }
576    }
577
578    Ok(None)
579}
580
581pub type Vec2 = [f32; 2];
582pub type Vec3 = [f32; 3];
583pub type Vec4 = [f32; 4];
584
585// Wrapper for Vec3 with Z defaulting to 0.0
586#[derive(Debug, Clone, Serialize)]
587pub struct Vec3DefaultZero(pub Vec3);
588
589impl Default for Vec3DefaultZero {
590    fn default() -> Self {
591        Vec3DefaultZero([0.0, 0.0, 0.0])
592    }
593}
594
595impl<'de> Deserialize<'de> for Vec3DefaultZero {
596    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
597    where
598        D: Deserializer<'de>,
599    {
600        struct Vec3Visitor;
601        impl<'de> serde::de::Visitor<'de> for Vec3Visitor {
602            type Value = Vec3DefaultZero;
603            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
604                formatter.write_str("a sequence of 2 or 3 floats")
605            }
606            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
607            where
608                A: SeqAccess<'de>,
609            {
610                let x = seq.next_element()?.unwrap_or(0.0);
611                let y = seq.next_element()?.unwrap_or(0.0);
612                let z = seq.next_element()?.unwrap_or(0.0);
613                // Consume remaining if any (shouldn't be)
614                while let Some(_) = seq.next_element::<f32>()? {}
615                Ok(Vec3DefaultZero([x, y, z]))
616            }
617        }
618        deserializer.deserialize_seq(Vec3Visitor)
619    }
620}
621
622// Wrapper for Vec3 with Z defaulting to 100.0 (for Scale)
623#[derive(Debug, Clone, Serialize)]
624pub struct Vec3Scale(pub Vec3);
625
626impl Default for Vec3Scale {
627    fn default() -> Self {
628        Vec3Scale([100.0, 100.0, 100.0])
629    }
630}
631
632impl<'de> Deserialize<'de> for Vec3Scale {
633    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
634    where
635        D: Deserializer<'de>,
636    {
637        struct Vec3ScaleVisitor;
638        impl<'de> serde::de::Visitor<'de> for Vec3ScaleVisitor {
639            type Value = Vec3Scale;
640            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
641                formatter.write_str("a sequence of 2 or 3 floats")
642            }
643            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
644            where
645                A: SeqAccess<'de>,
646            {
647                let x = seq.next_element()?.unwrap_or(0.0);
648                let y = seq.next_element()?.unwrap_or(0.0);
649                let z = seq.next_element()?.unwrap_or(100.0); // Default to 100%
650                while let Some(_) = seq.next_element::<f32>()? {}
651                Ok(Vec3Scale([x, y, z]))
652            }
653        }
654        deserializer.deserialize_seq(Vec3ScaleVisitor)
655    }
656}
657
658#[derive(Debug, Serialize, Deserialize, Clone, Default)]
659pub struct BezierPath {
660    #[serde(default)]
661    pub c: bool,
662    #[serde(default)]
663    pub i: Vec<Vec2>,
664    #[serde(default)]
665    pub o: Vec<Vec2>,
666    #[serde(default)]
667    pub v: Vec<Vec2>,
668}
669
670#[derive(Debug, Serialize, Deserialize, Clone)]
671pub struct Asset {
672    pub id: String,
673    #[serde(default)]
674    pub nm: Option<String>,
675    #[serde(default)]
676    pub layers: Option<Vec<Layer>>,
677    #[serde(default)]
678    pub w: Option<u32>,
679    #[serde(default)]
680    pub h: Option<u32>,
681    #[serde(default)]
682    pub u: Option<String>,
683    #[serde(default)]
684    pub p: Option<String>,
685    #[serde(default)]
686    pub e: Option<u8>,
687}
688
689#[derive(Debug, Serialize, Deserialize, Clone)]
690pub struct TextData {
691    pub d: Property<TextDocument>,
692    #[serde(default)]
693    pub a: Option<Vec<TextAnimatorData>>,
694}
695
696#[derive(Debug, Serialize, Deserialize, Clone, Default)]
697pub struct TextAnimatorData {
698    pub s: TextSelectorData,
699    pub a: TextStyleData,
700    #[serde(default)]
701    pub nm: Option<String>,
702}
703
704#[derive(Debug, Serialize, Deserialize, Clone, Default)]
705pub struct TextSelectorData {
706    #[serde(default)]
707    pub s: Option<Property<f32>>,
708    #[serde(default)]
709    pub e: Option<Property<f32>>,
710    #[serde(default)]
711    pub o: Option<Property<f32>>,
712}
713
714#[derive(Debug, Serialize, Deserialize, Clone, Default)]
715pub struct TextStyleData {
716    #[serde(default)]
717    pub p: Option<Property<Vec3DefaultZero>>, // Updated to Vec3
718    #[serde(default)]
719    pub s: Option<Property<Vec3Scale>>,       // Updated to Vec3Scale
720    #[serde(default)]
721    pub o: Option<Property<f32>>,
722    #[serde(default)]
723    pub r: Option<Property<f32>>,
724    #[serde(default)]
725    pub t: Option<Property<f32>>,
726    #[serde(default)]
727    pub fc: Option<Property<Vec4>>,
728    #[serde(default)]
729    pub sc: Option<Property<Vec4>>,
730}
731
732#[derive(Debug, Serialize, Deserialize, Clone, Default)]
733pub struct TextDocument {
734    #[serde(default)]
735    pub t: String,
736    #[serde(default)]
737    pub f: String,
738    #[serde(default)]
739    pub s: f32,
740    #[serde(default)]
741    pub j: u8,
742    #[serde(default)]
743    pub tr: f32,
744    #[serde(default)]
745    pub lh: f32,
746    #[serde(default)]
747    pub ls: Option<f32>,
748    #[serde(default)]
749    pub fc: Vec4,
750    #[serde(default)]
751    pub sc: Option<Vec4>,
752    #[serde(default)]
753    pub sw: Option<f32>,
754    #[serde(default)]
755    pub of: Option<bool>,
756    #[serde(default)]
757    pub sz: Option<Vec2>, // Size [w, h] for Box Text
758    #[serde(default)]
759    pub ps: Option<Vec2>, // Position [x, y] for Box Text
760}