1use crate::{
6 parsers::{parse_color, parse_property},
7 Color, TiledValue, Vec2,
8};
9use serde::{Deserialize, Deserializer};
10use std::collections::HashMap;
11
12#[derive(Deserialize, Debug, PartialEq, Clone)]
13pub struct Object {
14 pub gid: Option<u32>,
16 pub id: Option<u32>,
18 pub name: String,
19 #[serde(rename(deserialize = "type"), default)]
20 pub custom_type: String,
21 pub rotation: f32,
23 pub height: f32,
24 pub width: f32,
25 #[serde(default)]
27 pub x: f32,
28 #[serde(default)]
30 pub y: f32,
31 #[serde(deserialize_with = "parse_property", default)]
32 pub properties: HashMap<String, TiledValue>,
33 #[serde(flatten)]
44 pub object_type: ObjectType,
45}
46
47#[derive(Deserialize, Debug, PartialEq, Clone)]
48pub struct Text {
49 pub flags: u8,
51 #[serde(deserialize_with = "parse_color", default)]
52 pub color: Color,
53 pub text: String,
54}
55
56#[derive(Debug, PartialEq, Clone)]
58pub enum ObjectType {
59 Ellipse,
60 Point,
61 Polygon(Vec<Vec2<i32>>),
62 PolyLine(Vec<Vec2<i32>>),
63 Text(Text),
64 Template(String),
65 None,
66}
67
68impl ObjectType {
69 pub fn is_none(&self) -> bool {
70 *self == ObjectType::None
71 }
72
73 pub fn is_some(&self) -> bool {
74 *self != ObjectType::None
75 }
76}
77
78impl<'de> Deserialize<'de> for ObjectType {
79 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
80 where
81 D: Deserializer<'de>,
82 {
83 #[derive(Deserialize)]
84 #[serde(rename_all = "lowercase")]
85 enum Helper {
86 Ellipse(bool),
87 Point(bool),
88 Polygon(Vec<Vec2<i32>>),
89 Polyline(Vec<Vec2<i32>>),
90 Text {
91 bold: bool,
92 #[serde(deserialize_with = "parse_color", default)]
93 color: Color,
94 italic: bool,
95 text: String,
96 wrap: bool,
97 },
98 }
99
100 let v = serde_json::Value::deserialize(deserializer)?;
101 if let Ok(m) = Helper::deserialize(&v) {
102 return match m {
103 Helper::Ellipse(b) => {
104 if b {
105 Ok(ObjectType::Ellipse)
106 } else {
107 Ok(ObjectType::None)
108 }
109 }
110 Helper::Point(b) => {
111 if b {
112 Ok(ObjectType::Point)
113 } else {
114 Ok(ObjectType::None)
115 }
116 }
117 Helper::Polygon(data) => Ok(ObjectType::Polygon(data)),
118 Helper::Polyline(data) => Ok(ObjectType::PolyLine(data)),
119 Helper::Text {
120 bold,
121 color,
122 italic,
123 text,
124 wrap,
125 } => {
126 let mut flags = 0u8;
127 if bold {
128 flags |= 1
129 }
130 if italic {
131 flags |= 2
132 }
133 if wrap {
134 flags |= 4
135 }
136 Ok(ObjectType::Text(Text { flags, color, text }))
137 }
138 };
139 }
140 Ok(ObjectType::None)
141 }
142}