components store data instead of yaml

This commit is contained in:
2025-12-31 13:55:39 +09:00
parent 77db46198a
commit aebb5e6783
3 changed files with 295 additions and 201 deletions

View File

@@ -1,6 +1,7 @@
//! Component trait and generic component wrapper //! Component trait and generic component wrapper
use crate::model::UnityDocument; use crate::model::UnityDocument;
use crate::types::FileID;
use crate::types::FileRef; use crate::types::FileRef;
/// A trait for Unity components /// A trait for Unity components
@@ -15,8 +16,8 @@ pub trait Component {
true // Default implementation true // Default implementation
} }
/// Get the underlying UnityDocument /// Get the file ID of this component
fn document(&self) -> &UnityDocument; fn file_id(&self) -> FileID;
} }
/// A generic component wrapper that works with any component type /// A generic component wrapper that works with any component type
@@ -29,8 +30,8 @@ pub trait Component {
/// let file = UnityFile::from_path("Scene.unity")?; /// let file = UnityFile::from_path("Scene.unity")?;
/// for doc in &file.documents { /// for doc in &file.documents {
/// if !doc.is_game_object() { /// if !doc.is_game_object() {
/// if let Some(comp) = GenericComponent::new(doc) { /// if let Some(comp) = GenericComponent::parse(doc) {
/// println!("Component: {}", doc.class_name); /// println!("Component: {}", comp.class_name());
/// if let Some(go_ref) = comp.game_object() { /// if let Some(go_ref) = comp.game_object() {
/// println!(" Attached to: {}", go_ref.file_id); /// println!(" Attached to: {}", go_ref.file_id);
/// } /// }
@@ -39,52 +40,63 @@ pub trait Component {
/// } /// }
/// # Ok::<(), cursebreaker_parser::Error>(()) /// # Ok::<(), cursebreaker_parser::Error>(())
/// ``` /// ```
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct GenericComponent<'a> { pub struct GenericComponent {
document: &'a UnityDocument, file_id: FileID,
class_name: String,
game_object: Option<FileRef>,
is_enabled: bool,
} }
impl<'a> GenericComponent<'a> { impl GenericComponent {
/// Create a GenericComponent wrapper from a UnityDocument /// Parse a GenericComponent from a UnityDocument
/// ///
/// Returns None if the document is a GameObject (GameObjects are not components). /// Returns None if the document is a GameObject (GameObjects are not components).
pub fn new(document: &'a UnityDocument) -> Option<Self> { pub fn parse(document: &UnityDocument) -> Option<Self> {
if !document.is_game_object() { if document.is_game_object() {
Some(Self { document }) return None;
} else {
None
} }
// Extract m_GameObject and m_Enabled from the component properties
let props = document
.get(&document.class_name)
.and_then(|obj| obj.as_object());
let game_object = props
.and_then(|p| p.get("m_GameObject"))
.and_then(|v| v.as_file_ref())
.copied();
let is_enabled = props
.and_then(|p| p.get("m_Enabled"))
.and_then(|v| v.as_bool())
.unwrap_or(true);
Some(Self {
file_id: document.file_id,
class_name: document.class_name.clone(),
game_object,
is_enabled,
})
} }
/// Get the class name of this component /// Get the class name of this component
pub fn class_name(&self) -> &str { pub fn class_name(&self) -> &str {
&self.document.class_name &self.class_name
} }
} }
impl<'a> Component for GenericComponent<'a> { impl Component for GenericComponent {
fn game_object(&self) -> Option<FileRef> { fn game_object(&self) -> Option<FileRef> {
// Look for m_GameObject property which is common to all components self.game_object
self.document
.get(&self.document.class_name)
.and_then(|obj| obj.as_object())
.and_then(|props| props.get("m_GameObject"))
.and_then(|v| v.as_file_ref())
.copied()
} }
fn is_enabled(&self) -> bool { fn is_enabled(&self) -> bool {
// Look for m_Enabled property self.is_enabled
self.document
.get(&self.document.class_name)
.and_then(|obj| obj.as_object())
.and_then(|props| props.get("m_Enabled"))
.and_then(|v| v.as_bool())
.unwrap_or(true) // Default to enabled
} }
fn document(&self) -> &UnityDocument { fn file_id(&self) -> FileID {
self.document self.file_id
} }
} }
@@ -118,14 +130,14 @@ mod tests {
#[test] #[test]
fn test_component_creation() { fn test_component_creation() {
let doc = create_test_component(); let doc = create_test_component();
let comp = GenericComponent::new(&doc); let comp = GenericComponent::parse(&doc);
assert!(comp.is_some()); assert!(comp.is_some());
} }
#[test] #[test]
fn test_component_game_object_ref() { fn test_component_game_object_ref() {
let doc = create_test_component(); let doc = create_test_component();
let comp = GenericComponent::new(&doc).unwrap(); let comp = GenericComponent::parse(&doc).unwrap();
let go_ref = comp.game_object(); let go_ref = comp.game_object();
assert!(go_ref.is_some()); assert!(go_ref.is_some());
assert_eq!(go_ref.unwrap().file_id.as_i64(), 67890); assert_eq!(go_ref.unwrap().file_id.as_i64(), 67890);
@@ -134,17 +146,24 @@ mod tests {
#[test] #[test]
fn test_component_is_enabled() { fn test_component_is_enabled() {
let doc = create_test_component(); let doc = create_test_component();
let comp = GenericComponent::new(&doc).unwrap(); let comp = GenericComponent::parse(&doc).unwrap();
assert!(comp.is_enabled()); assert!(comp.is_enabled());
} }
#[test] #[test]
fn test_component_class_name() { fn test_component_class_name() {
let doc = create_test_component(); let doc = create_test_component();
let comp = GenericComponent::new(&doc).unwrap(); let comp = GenericComponent::parse(&doc).unwrap();
assert_eq!(comp.class_name(), "Transform"); assert_eq!(comp.class_name(), "Transform");
} }
#[test]
fn test_component_file_id() {
let doc = create_test_component();
let comp = GenericComponent::parse(&doc).unwrap();
assert_eq!(comp.file_id().as_i64(), 12345);
}
#[test] #[test]
fn test_game_object_is_not_component() { fn test_game_object_is_not_component() {
let mut properties = IndexMap::new(); let mut properties = IndexMap::new();
@@ -157,7 +176,7 @@ mod tests {
properties, properties,
}; };
let comp = GenericComponent::new(&doc); let comp = GenericComponent::parse(&doc);
assert!(comp.is_none()); assert!(comp.is_none());
} }
} }

View File

@@ -14,7 +14,7 @@ use crate::types::{FileID, FileRef};
/// ///
/// let file = UnityFile::from_path("Scene.unity")?; /// let file = UnityFile::from_path("Scene.unity")?;
/// for doc in &file.documents { /// for doc in &file.documents {
/// if let Some(go) = GameObject::new(doc) { /// if let Some(go) = GameObject::parse(doc) {
/// println!("GameObject: {}", go.name().unwrap_or("Unnamed")); /// println!("GameObject: {}", go.name().unwrap_or("Unnamed"));
/// println!(" Active: {}", go.is_active()); /// println!(" Active: {}", go.is_active());
/// println!(" Components: {}", go.components().len()); /// println!(" Components: {}", go.components().len());
@@ -22,66 +22,50 @@ use crate::types::{FileID, FileRef};
/// } /// }
/// # Ok::<(), cursebreaker_parser::Error>(()) /// # Ok::<(), cursebreaker_parser::Error>(())
/// ``` /// ```
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct GameObject<'a> { pub struct GameObject {
document: &'a UnityDocument, file_id: FileID,
name: Option<String>,
is_active: bool,
layer: Option<i64>,
tag: Option<i64>,
components: Vec<FileRef>,
} }
impl<'a> GameObject<'a> { impl GameObject {
/// Create a GameObject wrapper from a UnityDocument /// Parse a GameObject from a UnityDocument
/// ///
/// Returns None if the document is not a GameObject. /// Returns None if the document is not a GameObject.
pub fn new(document: &'a UnityDocument) -> Option<Self> { pub fn parse(document: &UnityDocument) -> Option<Self> {
if document.is_game_object() { if !document.is_game_object() {
Some(Self { document }) return None;
} else {
None
} }
}
/// Get the GameObject's name // Get the GameObject properties object
pub fn name(&self) -> Option<&str> { let props = document
self.document
.get("GameObject") .get("GameObject")
.and_then(|obj| obj.as_object()) .and_then(|obj| obj.as_object());
.and_then(|props| props.get("m_Name"))
let name = props
.and_then(|p| p.get("m_Name"))
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
} .map(|s| s.to_string());
/// Check if the GameObject is active let is_active = props
pub fn is_active(&self) -> bool { .and_then(|p| p.get("m_IsActive"))
self.document
.get("GameObject")
.and_then(|obj| obj.as_object())
.and_then(|props| props.get("m_IsActive"))
.and_then(|v| v.as_bool()) .and_then(|v| v.as_bool())
.unwrap_or(true) // Default to true if not specified .unwrap_or(true);
}
/// Get the GameObject's layer let layer = props
pub fn layer(&self) -> Option<i64> { .and_then(|p| p.get("m_Layer"))
self.document .and_then(|v| v.as_i64());
.get("GameObject")
.and_then(|obj| obj.as_object())
.and_then(|props| props.get("m_Layer"))
.and_then(|v| v.as_i64())
}
/// Get the GameObject's tag as a tag ID let tag = props
pub fn tag(&self) -> Option<i64> { .and_then(|p| p.get("m_TagString"))
self.document .and_then(|v| v.as_i64());
.get("GameObject")
.and_then(|obj| obj.as_object())
.and_then(|props| props.get("m_TagString"))
.and_then(|v| v.as_i64())
}
/// Get the list of component references attached to this GameObject let components = props
pub fn components(&self) -> Vec<FileRef> { .and_then(|p| p.get("m_Component"))
self.document
.get("GameObject")
.and_then(|obj| obj.as_object())
.and_then(|props| props.get("m_Component"))
.and_then(|v| v.as_array()) .and_then(|v| v.as_array())
.map(|arr| { .map(|arr| {
arr.iter() arr.iter()
@@ -94,17 +78,46 @@ impl<'a> GameObject<'a> {
}) })
.collect() .collect()
}) })
.unwrap_or_default() .unwrap_or_default();
Some(Self {
file_id: document.file_id,
name,
is_active,
layer,
tag,
components,
})
}
/// Get the GameObject's name
pub fn name(&self) -> Option<&str> {
self.name.as_deref()
}
/// Check if the GameObject is active
pub fn is_active(&self) -> bool {
self.is_active
}
/// Get the GameObject's layer
pub fn layer(&self) -> Option<i64> {
self.layer
}
/// Get the GameObject's tag as a tag ID
pub fn tag(&self) -> Option<i64> {
self.tag
}
/// Get the list of component references attached to this GameObject
pub fn components(&self) -> &[FileRef] {
&self.components
} }
/// Get the file ID of this GameObject /// Get the file ID of this GameObject
pub fn file_id(&self) -> FileID { pub fn file_id(&self) -> FileID {
self.document.file_id self.file_id
}
/// Get the underlying UnityDocument
pub fn document(&self) -> &'a UnityDocument {
self.document
} }
} }
@@ -136,35 +149,35 @@ mod tests {
#[test] #[test]
fn test_game_object_creation() { fn test_game_object_creation() {
let doc = create_test_game_object(); let doc = create_test_game_object();
let go = GameObject::new(&doc); let go = GameObject::parse(&doc);
assert!(go.is_some()); assert!(go.is_some());
} }
#[test] #[test]
fn test_game_object_name() { fn test_game_object_name() {
let doc = create_test_game_object(); let doc = create_test_game_object();
let go = GameObject::new(&doc).unwrap(); let go = GameObject::parse(&doc).unwrap();
assert_eq!(go.name(), Some("TestObject")); assert_eq!(go.name(), Some("TestObject"));
} }
#[test] #[test]
fn test_game_object_is_active() { fn test_game_object_is_active() {
let doc = create_test_game_object(); let doc = create_test_game_object();
let go = GameObject::new(&doc).unwrap(); let go = GameObject::parse(&doc).unwrap();
assert!(go.is_active()); assert!(go.is_active());
} }
#[test] #[test]
fn test_game_object_layer() { fn test_game_object_layer() {
let doc = create_test_game_object(); let doc = create_test_game_object();
let go = GameObject::new(&doc).unwrap(); let go = GameObject::parse(&doc).unwrap();
assert_eq!(go.layer(), Some(0)); assert_eq!(go.layer(), Some(0));
} }
#[test] #[test]
fn test_game_object_file_id() { fn test_game_object_file_id() {
let doc = create_test_game_object(); let doc = create_test_game_object();
let go = GameObject::new(&doc).unwrap(); let go = GameObject::parse(&doc).unwrap();
assert_eq!(go.file_id().as_i64(), 12345); assert_eq!(go.file_id().as_i64(), 12345);
} }
@@ -174,7 +187,7 @@ mod tests {
doc.type_id = 4; // Transform type ID doc.type_id = 4; // Transform type ID
doc.class_name = "Transform".to_string(); doc.class_name = "Transform".to_string();
let go = GameObject::new(&doc); let go = GameObject::parse(&doc);
assert!(go.is_none()); assert!(go.is_none());
} }
} }

View File

@@ -1,7 +1,7 @@
//! Transform and RectTransform component wrappers //! Transform and RectTransform component wrappers
use crate::model::UnityDocument; use crate::model::UnityDocument;
use crate::types::{Component, FileRef, Quaternion, Vector2, Vector3}; use crate::types::{Component, FileID, FileRef, Quaternion, Vector2, Vector3};
/// A wrapper around a UnityDocument that represents a Transform component /// A wrapper around a UnityDocument that represents a Transform component
/// ///
@@ -14,7 +14,7 @@ use crate::types::{Component, FileRef, Quaternion, Vector2, Vector3};
/// ///
/// let file = UnityFile::from_path("Scene.unity")?; /// let file = UnityFile::from_path("Scene.unity")?;
/// for doc in &file.documents { /// for doc in &file.documents {
/// if let Some(transform) = Transform::new(doc) { /// if let Some(transform) = Transform::parse(doc) {
/// if let Some(pos) = transform.local_position() { /// if let Some(pos) = transform.local_position() {
/// println!("Position: ({}, {}, {})", pos.x, pos.y, pos.z); /// println!("Position: ({}, {}, {})", pos.x, pos.y, pos.z);
/// } /// }
@@ -22,56 +22,58 @@ use crate::types::{Component, FileRef, Quaternion, Vector2, Vector3};
/// } /// }
/// # Ok::<(), cursebreaker_parser::Error>(()) /// # Ok::<(), cursebreaker_parser::Error>(())
/// ``` /// ```
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Transform<'a> { pub struct Transform {
document: &'a UnityDocument, file_id: FileID,
game_object: Option<FileRef>,
local_position: Option<Vector3>,
local_rotation: Option<Quaternion>,
local_scale: Option<Vector3>,
parent: Option<FileRef>,
children: Vec<FileRef>,
} }
impl<'a> Transform<'a> { impl Transform {
/// Create a Transform wrapper from a UnityDocument /// Parse a Transform from a UnityDocument
/// ///
/// Returns None if the document is not a Transform or RectTransform. /// Returns None if the document is not a Transform or RectTransform.
pub fn new(document: &'a UnityDocument) -> Option<Self> { pub fn parse(document: &UnityDocument) -> Option<Self> {
if document.class_name == "Transform" || document.class_name == "RectTransform" { if document.class_name != "Transform" && document.class_name != "RectTransform" {
Some(Self { document }) return None;
} else {
None
} }
}
/// Get the local position of this transform // Get the transform properties object
pub fn local_position(&self) -> Option<&Vector3> { let props = document
self.get_transform_props() .get(&document.class_name)
.and_then(|props| props.get("m_LocalPosition")) .and_then(|v| v.as_object());
.and_then(|v| v.as_vector3())
}
/// Get the local rotation of this transform let game_object = props
pub fn local_rotation(&self) -> Option<&Quaternion> { .and_then(|p| p.get("m_GameObject"))
self.get_transform_props()
.and_then(|props| props.get("m_LocalRotation"))
.and_then(|v| v.as_quaternion())
}
/// Get the local scale of this transform
pub fn local_scale(&self) -> Option<&Vector3> {
self.get_transform_props()
.and_then(|props| props.get("m_LocalScale"))
.and_then(|v| v.as_vector3())
}
/// Get the parent transform reference
pub fn parent(&self) -> Option<FileRef> {
self.get_transform_props()
.and_then(|props| props.get("m_Father"))
.and_then(|v| v.as_file_ref()) .and_then(|v| v.as_file_ref())
.copied() .copied();
}
/// Get the list of child transform references let local_position = props
pub fn children(&self) -> Vec<FileRef> { .and_then(|p| p.get("m_LocalPosition"))
self.get_transform_props() .and_then(|v| v.as_vector3())
.and_then(|props| props.get("m_Children")) .copied();
let local_rotation = props
.and_then(|p| p.get("m_LocalRotation"))
.and_then(|v| v.as_quaternion())
.copied();
let local_scale = props
.and_then(|p| p.get("m_LocalScale"))
.and_then(|v| v.as_vector3())
.copied();
let parent = props
.and_then(|p| p.get("m_Father"))
.and_then(|v| v.as_file_ref())
.copied();
let children = props
.and_then(|p| p.get("m_Children"))
.and_then(|v| v.as_array()) .and_then(|v| v.as_array())
.map(|arr| { .map(|arr| {
arr.iter() arr.iter()
@@ -79,31 +81,56 @@ impl<'a> Transform<'a> {
.copied() .copied()
.collect() .collect()
}) })
.unwrap_or_default() .unwrap_or_default();
Some(Self {
file_id: document.file_id,
game_object,
local_position,
local_rotation,
local_scale,
parent,
children,
})
} }
/// Helper to get the transform properties object /// Get the local position of this transform
fn get_transform_props(&self) -> Option<&indexmap::IndexMap<String, crate::property::PropertyValue>> { pub fn local_position(&self) -> Option<&Vector3> {
self.document self.local_position.as_ref()
.get(&self.document.class_name) }
.and_then(|v| v.as_object())
/// Get the local rotation of this transform
pub fn local_rotation(&self) -> Option<&Quaternion> {
self.local_rotation.as_ref()
}
/// Get the local scale of this transform
pub fn local_scale(&self) -> Option<&Vector3> {
self.local_scale.as_ref()
}
/// Get the parent transform reference
pub fn parent(&self) -> Option<FileRef> {
self.parent
}
/// Get the list of child transform references
pub fn children(&self) -> &[FileRef] {
&self.children
} }
} }
impl<'a> Component for Transform<'a> { impl Component for Transform {
fn game_object(&self) -> Option<FileRef> { fn game_object(&self) -> Option<FileRef> {
self.get_transform_props() self.game_object
.and_then(|props| props.get("m_GameObject"))
.and_then(|v| v.as_file_ref())
.copied()
} }
fn is_enabled(&self) -> bool { fn is_enabled(&self) -> bool {
true // Transforms are always enabled true // Transforms are always enabled
} }
fn document(&self) -> &UnityDocument { fn file_id(&self) -> FileID {
self.document self.file_id
} }
} }
@@ -118,7 +145,7 @@ impl<'a> Component for Transform<'a> {
/// ///
/// let file = UnityFile::from_path("Canvas.prefab")?; /// let file = UnityFile::from_path("Canvas.prefab")?;
/// for doc in &file.documents { /// for doc in &file.documents {
/// if let Some(rect_transform) = RectTransform::new(doc) { /// if let Some(rect_transform) = RectTransform::parse(doc) {
/// if let Some(anchor_min) = rect_transform.anchor_min() { /// if let Some(anchor_min) = rect_transform.anchor_min() {
/// println!("Anchor Min: ({}, {})", anchor_min.x, anchor_min.y); /// println!("Anchor Min: ({}, {})", anchor_min.x, anchor_min.y);
/// } /// }
@@ -126,58 +153,91 @@ impl<'a> Component for Transform<'a> {
/// } /// }
/// # Ok::<(), cursebreaker_parser::Error>(()) /// # Ok::<(), cursebreaker_parser::Error>(())
/// ``` /// ```
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct RectTransform<'a> { pub struct RectTransform {
transform: Transform<'a>, transform: Transform,
anchor_min: Option<Vector2>,
anchor_max: Option<Vector2>,
anchored_position: Option<Vector2>,
size_delta: Option<Vector2>,
pivot: Option<Vector2>,
} }
impl<'a> RectTransform<'a> { impl RectTransform {
/// Create a RectTransform wrapper from a UnityDocument /// Parse a RectTransform from a UnityDocument
/// ///
/// Returns None if the document is not a RectTransform. /// Returns None if the document is not a RectTransform.
pub fn new(document: &'a UnityDocument) -> Option<Self> { pub fn parse(document: &UnityDocument) -> Option<Self> {
if document.class_name == "RectTransform" { if document.class_name != "RectTransform" {
Some(Self { return None;
transform: Transform { document },
})
} else {
None
} }
// Parse the base Transform
let transform = Transform::parse(document)?;
// Get the RectTransform properties object
let props = document
.get("RectTransform")
.and_then(|v| v.as_object());
let anchor_min = props
.and_then(|p| p.get("m_AnchorMin"))
.and_then(|v| v.as_vector2())
.copied();
let anchor_max = props
.and_then(|p| p.get("m_AnchorMax"))
.and_then(|v| v.as_vector2())
.copied();
let anchored_position = props
.and_then(|p| p.get("m_AnchoredPosition"))
.and_then(|v| v.as_vector2())
.copied();
let size_delta = props
.and_then(|p| p.get("m_SizeDelta"))
.and_then(|v| v.as_vector2())
.copied();
let pivot = props
.and_then(|p| p.get("m_Pivot"))
.and_then(|v| v.as_vector2())
.copied();
Some(Self {
transform,
anchor_min,
anchor_max,
anchored_position,
size_delta,
pivot,
})
} }
/// Get the anchor min (bottom-left anchor) /// Get the anchor min (bottom-left anchor)
pub fn anchor_min(&self) -> Option<&Vector2> { pub fn anchor_min(&self) -> Option<&Vector2> {
self.get_rect_props() self.anchor_min.as_ref()
.and_then(|props| props.get("m_AnchorMin"))
.and_then(|v| v.as_vector2())
} }
/// Get the anchor max (top-right anchor) /// Get the anchor max (top-right anchor)
pub fn anchor_max(&self) -> Option<&Vector2> { pub fn anchor_max(&self) -> Option<&Vector2> {
self.get_rect_props() self.anchor_max.as_ref()
.and_then(|props| props.get("m_AnchorMax"))
.and_then(|v| v.as_vector2())
} }
/// Get the anchored position /// Get the anchored position
pub fn anchored_position(&self) -> Option<&Vector2> { pub fn anchored_position(&self) -> Option<&Vector2> {
self.get_rect_props() self.anchored_position.as_ref()
.and_then(|props| props.get("m_AnchoredPosition"))
.and_then(|v| v.as_vector2())
} }
/// Get the size delta /// Get the size delta
pub fn size_delta(&self) -> Option<&Vector2> { pub fn size_delta(&self) -> Option<&Vector2> {
self.get_rect_props() self.size_delta.as_ref()
.and_then(|props| props.get("m_SizeDelta"))
.and_then(|v| v.as_vector2())
} }
/// Get the pivot point /// Get the pivot point
pub fn pivot(&self) -> Option<&Vector2> { pub fn pivot(&self) -> Option<&Vector2> {
self.get_rect_props() self.pivot.as_ref()
.and_then(|props| props.get("m_Pivot"))
.and_then(|v| v.as_vector2())
} }
/// Get the local position (from Transform) /// Get the local position (from Transform)
@@ -201,17 +261,12 @@ impl<'a> RectTransform<'a> {
} }
/// Get the list of child transform references (from Transform) /// Get the list of child transform references (from Transform)
pub fn children(&self) -> Vec<FileRef> { pub fn children(&self) -> &[FileRef] {
self.transform.children() self.transform.children()
} }
/// Helper to get the RectTransform properties object
fn get_rect_props(&self) -> Option<&indexmap::IndexMap<String, crate::property::PropertyValue>> {
self.transform.get_transform_props()
}
} }
impl<'a> Component for RectTransform<'a> { impl Component for RectTransform {
fn game_object(&self) -> Option<FileRef> { fn game_object(&self) -> Option<FileRef> {
self.transform.game_object() self.transform.game_object()
} }
@@ -220,8 +275,8 @@ impl<'a> Component for RectTransform<'a> {
self.transform.is_enabled() self.transform.is_enabled()
} }
fn document(&self) -> &UnityDocument { fn file_id(&self) -> FileID {
self.transform.document() self.transform.file_id()
} }
} }
@@ -314,14 +369,14 @@ mod tests {
#[test] #[test]
fn test_transform_creation() { fn test_transform_creation() {
let doc = create_test_transform(); let doc = create_test_transform();
let transform = Transform::new(&doc); let transform = Transform::parse(&doc);
assert!(transform.is_some()); assert!(transform.is_some());
} }
#[test] #[test]
fn test_transform_local_position() { fn test_transform_local_position() {
let doc = create_test_transform(); let doc = create_test_transform();
let transform = Transform::new(&doc).unwrap(); let transform = Transform::parse(&doc).unwrap();
let pos = transform.local_position().unwrap(); let pos = transform.local_position().unwrap();
assert_eq!(pos.x, 1.0); assert_eq!(pos.x, 1.0);
assert_eq!(pos.y, 2.0); assert_eq!(pos.y, 2.0);
@@ -331,7 +386,7 @@ mod tests {
#[test] #[test]
fn test_transform_local_rotation() { fn test_transform_local_rotation() {
let doc = create_test_transform(); let doc = create_test_transform();
let transform = Transform::new(&doc).unwrap(); let transform = Transform::parse(&doc).unwrap();
let rot = transform.local_rotation().unwrap(); let rot = transform.local_rotation().unwrap();
assert_eq!(rot.w, 1.0); assert_eq!(rot.w, 1.0);
} }
@@ -339,22 +394,29 @@ mod tests {
#[test] #[test]
fn test_transform_local_scale() { fn test_transform_local_scale() {
let doc = create_test_transform(); let doc = create_test_transform();
let transform = Transform::new(&doc).unwrap(); let transform = Transform::parse(&doc).unwrap();
let scale = transform.local_scale().unwrap(); let scale = transform.local_scale().unwrap();
assert_eq!(scale, &Vector3::ONE); assert_eq!(scale, &Vector3::ONE);
} }
#[test]
fn test_transform_file_id() {
let doc = create_test_transform();
let transform = Transform::parse(&doc).unwrap();
assert_eq!(transform.file_id().as_i64(), 12345);
}
#[test] #[test]
fn test_rect_transform_creation() { fn test_rect_transform_creation() {
let doc = create_test_rect_transform(); let doc = create_test_rect_transform();
let rect_transform = RectTransform::new(&doc); let rect_transform = RectTransform::parse(&doc);
assert!(rect_transform.is_some()); assert!(rect_transform.is_some());
} }
#[test] #[test]
fn test_rect_transform_anchor_min() { fn test_rect_transform_anchor_min() {
let doc = create_test_rect_transform(); let doc = create_test_rect_transform();
let rect_transform = RectTransform::new(&doc).unwrap(); let rect_transform = RectTransform::parse(&doc).unwrap();
let anchor_min = rect_transform.anchor_min().unwrap(); let anchor_min = rect_transform.anchor_min().unwrap();
assert_eq!(anchor_min, &Vector2::ZERO); assert_eq!(anchor_min, &Vector2::ZERO);
} }
@@ -362,7 +424,7 @@ mod tests {
#[test] #[test]
fn test_rect_transform_anchor_max() { fn test_rect_transform_anchor_max() {
let doc = create_test_rect_transform(); let doc = create_test_rect_transform();
let rect_transform = RectTransform::new(&doc).unwrap(); let rect_transform = RectTransform::parse(&doc).unwrap();
let anchor_max = rect_transform.anchor_max().unwrap(); let anchor_max = rect_transform.anchor_max().unwrap();
assert_eq!(anchor_max, &Vector2::ONE); assert_eq!(anchor_max, &Vector2::ONE);
} }
@@ -370,7 +432,7 @@ mod tests {
#[test] #[test]
fn test_rect_transform_size_delta() { fn test_rect_transform_size_delta() {
let doc = create_test_rect_transform(); let doc = create_test_rect_transform();
let rect_transform = RectTransform::new(&doc).unwrap(); let rect_transform = RectTransform::parse(&doc).unwrap();
let size_delta = rect_transform.size_delta().unwrap(); let size_delta = rect_transform.size_delta().unwrap();
assert_eq!(size_delta.x, 100.0); assert_eq!(size_delta.x, 100.0);
assert_eq!(size_delta.y, 50.0); assert_eq!(size_delta.y, 50.0);
@@ -379,7 +441,7 @@ mod tests {
#[test] #[test]
fn test_rect_transform_pivot() { fn test_rect_transform_pivot() {
let doc = create_test_rect_transform(); let doc = create_test_rect_transform();
let rect_transform = RectTransform::new(&doc).unwrap(); let rect_transform = RectTransform::parse(&doc).unwrap();
let pivot = rect_transform.pivot().unwrap(); let pivot = rect_transform.pivot().unwrap();
assert_eq!(pivot.x, 0.5); assert_eq!(pivot.x, 0.5);
assert_eq!(pivot.y, 0.5); assert_eq!(pivot.y, 0.5);
@@ -388,7 +450,7 @@ mod tests {
#[test] #[test]
fn test_rect_transform_inherits_from_transform() { fn test_rect_transform_inherits_from_transform() {
let doc = create_test_rect_transform(); let doc = create_test_rect_transform();
let rect_transform = RectTransform::new(&doc).unwrap(); let rect_transform = RectTransform::parse(&doc).unwrap();
// Test inherited methods // Test inherited methods
assert!(rect_transform.local_position().is_some()); assert!(rect_transform.local_position().is_some());