1use std::collections::HashMap;
7use std::sync::{Arc, RwLock};
8
9pub const UNITY_TAG_URI: &str = "tag:unity3d.com,2011:";
11
12pub const UNITY_YAML_VERSION: (u32, u32) = (1, 1);
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum LineEnding {
18 Unix, Windows, Mac, }
22
23impl Default for LineEnding {
24 fn default() -> Self {
25 #[cfg(windows)]
26 return LineEnding::Windows;
27 #[cfg(not(windows))]
28 return LineEnding::Unix;
29 }
30}
31
32impl LineEnding {
33 pub fn as_str(&self) -> &'static str {
34 match self {
35 LineEnding::Unix => "\n",
36 LineEnding::Windows => "\r\n",
37 LineEnding::Mac => "\r",
38 }
39 }
40
41 pub fn from_string(s: &str) -> Self {
43 match s {
44 "\n" => LineEnding::Unix,
45 "\r\n" => LineEnding::Windows,
46 "\r" => LineEnding::Mac,
47 _ => LineEnding::default(),
48 }
49 }
50}
51
52pub struct UnityClassIdMap {
55 map: Arc<RwLock<HashMap<String, String>>>,
56}
57
58impl UnityClassIdMap {
59 pub fn new() -> Self {
60 Self {
61 map: Arc::new(RwLock::new(HashMap::new())),
62 }
63 }
64
65 pub fn get_or_create(&self, class_id: &str, class_name: &str) -> String {
67 let key = format!("{}-{}", class_id, class_name);
68
69 if let Ok(map) = self.map.read()
71 && let Some(existing) = map.get(&key)
72 {
73 return existing.clone();
74 }
75
76 if let Ok(mut map) = self.map.write() {
78 map.insert(key.clone(), class_name.to_string());
79 }
80
81 class_name.to_string()
82 }
83
84 pub fn clear(&self) {
86 if let Ok(mut map) = self.map.write() {
87 map.clear();
88 }
89 }
90
91 pub fn get_class_name(&self, class_id: i32) -> Option<String> {
93 self.get_class_name_str(class_id).map(str::to_string)
94 }
95
96 pub fn get_class_name_str(&self, class_id: i32) -> Option<&'static str> {
98 class_id_name(class_id)
99 }
100}
101
102fn class_id_name(class_id: i32) -> Option<&'static str> {
103 match class_id {
104 0 => Some("Object"),
106 1 => Some("GameObject"),
107 2 => Some("Component"),
108 4 => Some("Transform"),
109 8 => Some("Behaviour"),
110
111 3 => Some("LevelGameManager"),
113 5 => Some("TimeManager"),
114 6 => Some("GlobalGameManager"),
115 9 => Some("GameManager"),
116 11 => Some("AudioManager"),
117 13 => Some("InputManager"),
118
119 20 => Some("Camera"),
121 21 => Some("Material"),
122 23 => Some("MeshRenderer"),
123 25 => Some("Renderer"),
124 27 => Some("Texture"),
125 28 => Some("Texture2D"),
126 33 => Some("MeshFilter"),
127 43 => Some("Mesh"),
128 48 => Some("Shader"),
129
130 49 => Some("TextAsset"),
132 74 => Some("AnimationClip"),
133 83 => Some("AudioClip"),
134 89 => Some("CubemapArray"),
135 90 => Some("Avatar"),
136 91 => Some("AnimatorController"),
137 95 => Some("Animator"),
138 108 => Some("Light"),
139 114 => Some("MonoBehaviour"),
140 115 => Some("MonoScript"),
141 128 => Some("Font"),
142 142 => Some("AssetBundle"),
143 152 => Some("MovieTexture"),
144 184 => Some("RenderTexture"),
145 212 => Some("SpriteRenderer"),
146 213 => Some("Sprite"),
147 1001 => Some("PrefabInstance"),
148
149 50 => Some("Rigidbody2D"),
151 54 => Some("Rigidbody"),
152 56 => Some("Collider"),
153
154 687078895 => Some("SpriteAtlas"),
156
157 _ => None,
158 }
159}
160
161impl Default for UnityClassIdMap {
162 fn default() -> Self {
163 Self::new()
164 }
165}
166
167lazy_static::lazy_static! {
168 pub static ref GLOBAL_CLASS_ID_MAP: UnityClassIdMap = UnityClassIdMap::new();
170}
171
172pub mod class_ids {
174 pub const OBJECT: i32 = 0;
175 pub const GAME_OBJECT: i32 = 1;
176 pub const COMPONENT: i32 = 2;
177 pub const BEHAVIOUR: i32 = 8;
178 pub const TRANSFORM: i32 = 4;
179 pub const CAMERA: i32 = 20;
180 pub const MATERIAL: i32 = 21;
181 pub const MESH_RENDERER: i32 = 23;
182 pub const TEXTURE_2D: i32 = 28;
183 pub const MESH: i32 = 43;
184 pub const SHADER: i32 = 48;
185 pub const TEXTURE: i32 = 27;
186 pub const TEXT_ASSET: i32 = 49;
187 pub const ANIMATION_CLIP: i32 = 74;
188 pub const AUDIO_CLIP: i32 = 83;
189 pub const ANIMATOR_CONTROLLER: i32 = 91;
190 pub const MONO_BEHAVIOUR: i32 = 114;
191 pub const MONO_SCRIPT: i32 = 115;
192 pub const ASSET_BUNDLE: i32 = 142;
193 pub const SPRITE_RENDERER: i32 = 212;
194 pub const SPRITE: i32 = 213;
195 pub const PREFAB_INSTANCE: i32 = 1001;
196 pub const SPRITE_ATLAS: i32 = 687078895;
197}
198
199pub mod class_names {
201 pub const OBJECT: &str = "Object";
202 pub const GAME_OBJECT: &str = "GameObject";
203 pub const COMPONENT: &str = "Component";
204 pub const TRANSFORM: &str = "Transform";
205 pub const CAMERA: &str = "Camera";
206 pub const MATERIAL: &str = "Material";
207 pub const MESH_RENDERER: &str = "MeshRenderer";
208 pub const TEXTURE_2D: &str = "Texture2D";
209 pub const MESH: &str = "Mesh";
210 pub const SHADER: &str = "Shader";
211 pub const TEXTURE: &str = "Texture";
212 pub const SPRITE: &str = "Sprite";
213 pub const MONO_BEHAVIOUR: &str = "MonoBehaviour";
214 pub const MONO_SCRIPT: &str = "MonoScript";
215 pub const PREFAB_INSTANCE: &str = "PrefabInstance";
216 pub const SPRITE_ATLAS: &str = "SpriteAtlas";
217}
218
219#[cfg(test)]
220mod tests {
221 use super::*;
222
223 #[test]
224 fn test_line_ending() {
225 assert_eq!(LineEnding::Unix.as_str(), "\n");
226 assert_eq!(LineEnding::Windows.as_str(), "\r\n");
227 assert_eq!(LineEnding::Mac.as_str(), "\r");
228 }
229
230 #[test]
231 fn test_common_class_ids() {
232 assert_eq!(class_ids::OBJECT, 0);
233 assert_eq!(class_ids::GAME_OBJECT, 1);
234 assert_eq!(class_ids::COMPONENT, 2);
235 assert_eq!(class_ids::TRANSFORM, 4);
236 assert_eq!(class_ids::BEHAVIOUR, 8);
237 assert_eq!(class_ids::SPRITE_RENDERER, 212);
238 assert_eq!(class_ids::SPRITE, 213);
239
240 assert_eq!(
241 GLOBAL_CLASS_ID_MAP.get_class_name(class_ids::SPRITE),
242 Some("Sprite".to_string())
243 );
244 assert_eq!(
245 GLOBAL_CLASS_ID_MAP.get_class_name(class_ids::SPRITE_RENDERER),
246 Some("SpriteRenderer".to_string())
247 );
248
249 assert_eq!(GLOBAL_CLASS_ID_MAP.get_class_name(256), None);
251 assert_eq!(GLOBAL_CLASS_ID_MAP.get_class_name(512), None);
252 assert_eq!(GLOBAL_CLASS_ID_MAP.get_class_name(768), None);
253 }
254
255 #[test]
256 fn test_class_id_map() {
257 let map = UnityClassIdMap::new();
258 let result = map.get_or_create("1", "GameObject");
259 assert_eq!(result, "GameObject");
260
261 let result2 = map.get_or_create("1", "GameObject");
263 assert_eq!(result2, "GameObject");
264 }
265}