vmt_parser/data/
texture_transform.rs1use serde::de::Error;
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3use std::borrow::Cow;
4use std::fmt::{Display, Formatter};
5use std::str::FromStr;
6
7#[derive(Debug, PartialEq, Clone)]
8pub struct TextureTransform {
9 pub center: [f32; 2],
10 pub scale: [f32; 2],
11 pub rotate: f32,
12 pub translate: [f32; 2],
13}
14
15impl Default for TextureTransform {
16 fn default() -> Self {
17 TextureTransform {
18 center: [0.5; 2],
19 scale: [1.0; 2],
20 rotate: 0.0,
21 translate: [0.0; 2],
22 }
23 }
24}
25
26impl Display for TextureTransform {
27 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
28 write!(
29 f,
30 "center {} {} scale {} {} rotate {} translate {} {}",
31 self.center[0],
32 self.center[1],
33 self.scale[0],
34 self.scale[1],
35 self.rotate,
36 self.translate[0],
37 self.translate[1],
38 )
39 }
40}
41
42#[test]
43fn test_parse_base_texture_transform() {
44 assert_eq!(
45 TextureTransform {
46 center: [0.5; 2],
47 scale: [1.0; 2],
48 rotate: 0.0,
49 translate: [0.0; 2],
50 },
51 TextureTransform::from_str("center .5 .5 scale 1 1 rotate 0 translate 0 0").unwrap()
52 );
53 assert_eq!(
54 TextureTransform {
55 center: [0.2, 0.3],
56 scale: [1.1, 1.2],
57 rotate: 1.0,
58 translate: [0.4, 0.5],
59 },
60 TextureTransform::from_str("center .2 .3 scale 1.1 1.2 rotate 1 translate 0.4 0.5")
61 .unwrap()
62 );
63}
64
65impl FromStr for TextureTransform {
66 type Err = &'static str;
67
68 fn from_str(str: &str) -> Result<Self, Self::Err> {
69 let mut parts = str.split(' ').filter(|p| !p.is_empty());
70 match (
71 parts.next(),
72 parts.next().and_then(|val| f32::from_str(val).ok()),
73 parts.next().and_then(|val| f32::from_str(val).ok()),
74 parts.next(),
75 parts.next().and_then(|val| f32::from_str(val).ok()),
76 parts.next().and_then(|val| f32::from_str(val).ok()),
77 parts.next(),
78 parts.next().and_then(|val| f32::from_str(val).ok()),
79 parts.next(),
80 parts.next().and_then(|val| f32::from_str(val).ok()),
81 parts.next().and_then(|val| f32::from_str(val).ok()),
82 ) {
83 (
84 Some("center"),
85 Some(center_x),
86 Some(center_y),
87 Some("scale"),
88 Some(scale_x),
89 Some(scale_y),
90 Some("rotate"),
91 Some(rotate),
92 Some("translate"),
93 Some(translate_x),
94 Some(translate_y),
95 ) => Ok(TextureTransform {
96 center: [center_x, center_y],
97 scale: [scale_x, scale_y],
98 rotate,
99 translate: [translate_x, translate_y],
100 }),
101 _ => Err("invalid $basetexturetransform format"),
102 }
103 }
104}
105
106impl<'de> Deserialize<'de> for TextureTransform {
107 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
108 where
109 D: Deserializer<'de>,
110 {
111 let str = Cow::<str>::deserialize(deserializer)?;
112 Self::from_str(str.as_ref()).map_err(D::Error::custom)
113 }
114}
115
116impl Serialize for TextureTransform {
117 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
118 where
119 S: Serializer,
120 {
121 serializer.serialize_str(&self.to_string())
122 }
123}