unity_asset_binary/metadata/
types.rs

1//! Metadata type definitions
2//!
3//! This module defines all the data structures used for Unity asset metadata extraction.
4
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7
8/// Comprehensive metadata for a Unity asset
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct AssetMetadata {
11    /// Basic file information
12    pub file_info: FileInfo,
13    /// Object statistics
14    pub object_stats: ObjectStatistics,
15    /// Dependency information
16    pub dependencies: DependencyInfo,
17    /// Asset relationships
18    pub relationships: AssetRelationships,
19    /// Performance metrics
20    pub performance: PerformanceMetrics,
21}
22
23/// Basic file information
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct FileInfo {
26    pub file_size: u64,
27    pub unity_version: String,
28    pub target_platform: String,
29    pub compression_type: String,
30    pub file_format_version: u32,
31}
32
33/// Object statistics within the asset
34#[derive(Debug, Clone, Serialize, Deserialize, Default)]
35pub struct ObjectStatistics {
36    pub total_objects: usize,
37    pub objects_by_type: HashMap<String, usize>,
38    pub largest_objects: Vec<ObjectSummary>,
39    pub memory_usage: MemoryUsage,
40}
41
42/// Summary of an individual object
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct ObjectSummary {
45    pub path_id: i64,
46    pub class_name: String,
47    pub name: Option<String>,
48    pub byte_size: u32,
49    pub dependencies: Vec<i64>,
50}
51
52/// Memory usage statistics
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct MemoryUsage {
55    pub total_bytes: u64,
56    pub by_type: HashMap<String, u64>,
57    pub largest_type: Option<String>,
58    pub average_object_size: f64,
59}
60
61impl Default for MemoryUsage {
62    fn default() -> Self {
63        Self {
64            total_bytes: 0,
65            by_type: HashMap::new(),
66            largest_type: None,
67            average_object_size: 0.0,
68        }
69    }
70}
71
72/// Dependency information
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct DependencyInfo {
75    pub external_references: Vec<ExternalReference>,
76    pub internal_references: Vec<InternalReference>,
77    pub dependency_graph: DependencyGraph,
78    pub circular_dependencies: Vec<Vec<i64>>,
79}
80
81/// External file reference
82#[derive(Debug, Clone, Serialize, Deserialize)]
83pub struct ExternalReference {
84    pub file_id: i32,
85    pub path_id: i64,
86    pub referenced_by: Vec<i64>,
87    /// Best-effort resolved external file path (from `SerializedFile.externals`)
88    pub file_path: Option<String>,
89    /// Best-effort resolved external file GUID (from `SerializedFile.externals`)
90    pub guid: Option<[u8; 16]>,
91}
92
93/// Internal object reference
94#[derive(Debug, Clone, Serialize, Deserialize)]
95pub struct InternalReference {
96    pub from_object: i64,
97    pub to_object: i64,
98    pub reference_type: String,
99}
100
101/// Dependency graph representation
102#[derive(Debug, Clone, Serialize, Deserialize)]
103pub struct DependencyGraph {
104    pub nodes: Vec<i64>,
105    pub edges: Vec<(i64, i64)>,
106    pub root_objects: Vec<i64>,
107    pub leaf_objects: Vec<i64>,
108}
109
110/// Asset relationships and hierarchy
111#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct AssetRelationships {
113    pub gameobject_hierarchy: Vec<GameObjectHierarchy>,
114    pub component_relationships: Vec<ComponentRelationship>,
115    pub asset_references: Vec<AssetReference>,
116}
117
118/// GameObject hierarchy information
119#[derive(Debug, Clone, Serialize, Deserialize)]
120pub struct GameObjectHierarchy {
121    pub gameobject_id: i64,
122    pub name: String,
123    pub parent_id: Option<i64>,
124    pub children_ids: Vec<i64>,
125    pub transform_id: i64,
126    pub components: Vec<i64>,
127    pub depth: u32,
128}
129
130/// Component relationship information
131#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct ComponentRelationship {
133    pub component_id: i64,
134    pub component_type: String,
135    pub gameobject_id: i64,
136    pub dependencies: Vec<i64>,
137    pub external_dependencies: Vec<ExternalObjectRef>,
138}
139
140/// External object reference (PPtr where `fileID > 0`)
141#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
142pub struct ExternalObjectRef {
143    pub file_id: i32,
144    pub path_id: i64,
145    pub file_path: Option<String>,
146    pub guid: Option<[u8; 16]>,
147}
148
149/// Asset reference information
150#[derive(Debug, Clone, Serialize, Deserialize)]
151pub struct AssetReference {
152    pub asset_id: i64,
153    pub asset_type: String,
154    pub referenced_by: Vec<i64>,
155    pub file_path: Option<String>,
156}
157
158/// Performance metrics
159#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct PerformanceMetrics {
161    pub parse_time_ms: f64,
162    pub memory_peak_mb: f64,
163    pub object_parse_rate: f64, // objects per second
164    pub complexity_score: f64,
165}
166
167/// Metadata extraction configuration
168#[derive(Debug, Clone)]
169pub struct ExtractionConfig {
170    /// Whether to include dependency analysis
171    pub include_dependencies: bool,
172    /// Whether to include hierarchy analysis
173    pub include_hierarchy: bool,
174    /// Maximum number of objects to analyze (0 = no limit)
175    pub max_objects: Option<usize>,
176    /// Whether to include performance metrics
177    pub include_performance: bool,
178    /// Whether to extract detailed object summaries
179    pub include_object_details: bool,
180}
181
182impl Default for ExtractionConfig {
183    fn default() -> Self {
184        Self {
185            include_dependencies: true,
186            include_hierarchy: true,
187            max_objects: None,
188            include_performance: true,
189            include_object_details: true,
190        }
191    }
192}
193
194/// Metadata extraction result
195#[derive(Debug, Clone)]
196pub struct ExtractionResult {
197    pub metadata: AssetMetadata,
198    pub warnings: Vec<String>,
199    pub errors: Vec<String>,
200}
201
202impl ExtractionResult {
203    pub fn new(metadata: AssetMetadata) -> Self {
204        Self {
205            metadata,
206            warnings: Vec::new(),
207            errors: Vec::new(),
208        }
209    }
210
211    pub fn add_warning(&mut self, warning: String) {
212        self.warnings.push(warning);
213    }
214
215    pub fn add_error(&mut self, error: String) {
216        self.errors.push(error);
217    }
218
219    pub fn has_warnings(&self) -> bool {
220        !self.warnings.is_empty()
221    }
222
223    pub fn has_errors(&self) -> bool {
224        !self.errors.is_empty()
225    }
226}
227
228/// Statistics about the extraction process
229#[derive(Debug, Clone)]
230pub struct ExtractionStats {
231    pub objects_processed: usize,
232    pub dependencies_found: usize,
233    pub relationships_found: usize,
234    pub processing_time_ms: f64,
235    pub memory_used_mb: f64,
236}
237
238impl Default for ExtractionStats {
239    fn default() -> Self {
240        Self {
241            objects_processed: 0,
242            dependencies_found: 0,
243            relationships_found: 0,
244            processing_time_ms: 0.0,
245            memory_used_mb: 0.0,
246        }
247    }
248}
249
250/// Unity class ID constants for metadata extraction (single source of truth: `unity-asset-core`)
251pub use unity_asset_core::class_ids;
252
253/// Helper functions for metadata types
254impl AssetMetadata {
255    /// Create a new empty metadata structure
256    pub fn new() -> Self {
257        Self {
258            file_info: FileInfo {
259                file_size: 0,
260                unity_version: String::new(),
261                target_platform: String::new(),
262                compression_type: String::new(),
263                file_format_version: 0,
264            },
265            object_stats: ObjectStatistics::default(),
266            dependencies: DependencyInfo {
267                external_references: Vec::new(),
268                internal_references: Vec::new(),
269                dependency_graph: DependencyGraph {
270                    nodes: Vec::new(),
271                    edges: Vec::new(),
272                    root_objects: Vec::new(),
273                    leaf_objects: Vec::new(),
274                },
275                circular_dependencies: Vec::new(),
276            },
277            relationships: AssetRelationships {
278                gameobject_hierarchy: Vec::new(),
279                component_relationships: Vec::new(),
280                asset_references: Vec::new(),
281            },
282            performance: PerformanceMetrics {
283                parse_time_ms: 0.0,
284                memory_peak_mb: 0.0,
285                object_parse_rate: 0.0,
286                complexity_score: 0.0,
287            },
288        }
289    }
290
291    /// Get total number of objects
292    pub fn total_objects(&self) -> usize {
293        self.object_stats.total_objects
294    }
295
296    /// Get total memory usage
297    pub fn total_memory_bytes(&self) -> u64 {
298        self.object_stats.memory_usage.total_bytes
299    }
300
301    /// Check if the asset has dependencies
302    pub fn has_dependencies(&self) -> bool {
303        !self.dependencies.external_references.is_empty()
304            || !self.dependencies.internal_references.is_empty()
305    }
306
307    /// Check if the asset has hierarchy information
308    pub fn has_hierarchy(&self) -> bool {
309        !self.relationships.gameobject_hierarchy.is_empty()
310    }
311}
312
313impl Default for AssetMetadata {
314    fn default() -> Self {
315        Self::new()
316    }
317}