use crate::error::Result;
use crate::extension::ExtensionHandler;
use crate::model::{Extension, Model};
use crate::validator::{
validate_component_chain, validate_duplicate_uuids, validate_production_extension,
validate_production_paths, validate_production_uuids_required, validate_uuid_formats,
};
pub struct ProductionExtensionHandler;
impl ExtensionHandler for ProductionExtensionHandler {
fn extension_type(&self) -> Extension {
Extension::Production
}
fn validate(&self, model: &Model) -> Result<()> {
validate_production_extension(model)?;
validate_production_paths(model)?;
validate_uuid_formats(model)?;
validate_production_uuids_required(model)?;
validate_duplicate_uuids(model)?;
validate_component_chain(model)?;
Ok(())
}
fn is_used_in_model(&self, model: &Model) -> bool {
let has_object_production = model
.resources
.objects
.iter()
.any(|obj| obj.production.is_some());
let has_build_production = model
.build
.items
.iter()
.any(|item| item.production_uuid.is_some() || item.production_path.is_some());
let has_build_uuid = model.build.production_uuid.is_some();
has_object_production || has_build_production || has_build_uuid
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::model::{BuildItem, Object, ProductionInfo};
#[test]
fn test_extension_type() {
let handler = ProductionExtensionHandler;
assert_eq!(handler.extension_type(), Extension::Production);
}
#[test]
fn test_namespace() {
let handler = ProductionExtensionHandler;
assert_eq!(
handler.namespace(),
"http://schemas.microsoft.com/3dmanufacturing/production/2015/06"
);
}
#[test]
fn test_name() {
let handler = ProductionExtensionHandler;
assert_eq!(handler.name(), "Production");
}
#[test]
fn test_is_used_in_model_empty() {
let handler = ProductionExtensionHandler;
let model = Model::new();
assert!(!handler.is_used_in_model(&model));
}
#[test]
fn test_is_used_in_model_with_object_production() {
let handler = ProductionExtensionHandler;
let mut model = Model::new();
let mut obj = Object::new(1);
obj.production = Some(ProductionInfo::with_uuid("test-uuid".to_string()));
model.resources.objects.push(obj);
assert!(handler.is_used_in_model(&model));
}
#[test]
fn test_is_used_in_model_with_build_item_production() {
let handler = ProductionExtensionHandler;
let mut model = Model::new();
let mut item = BuildItem::new(1);
item.production_uuid = Some("build-item-uuid".to_string());
model.build.items.push(item);
assert!(handler.is_used_in_model(&model));
}
#[test]
fn test_is_used_in_model_with_build_production_uuid() {
let handler = ProductionExtensionHandler;
let mut model = Model::new();
model.build.production_uuid = Some("build-uuid".to_string());
assert!(handler.is_used_in_model(&model));
}
#[test]
fn test_validate_empty_model() {
let handler = ProductionExtensionHandler;
let model = Model::new();
assert!(handler.validate(&model).is_ok());
}
#[test]
fn test_validate_valid_production_path() {
let handler = ProductionExtensionHandler;
let mut model = Model::new();
let mut obj = Object::new(1);
obj.production = Some(ProductionInfo {
uuid: Some("12345678-1234-1234-1234-123456789012".to_string()),
path: Some("/3D/other_part.model".to_string()),
});
model.resources.objects.push(obj);
assert!(handler.validate(&model).is_ok());
}
#[test]
fn test_validate_invalid_production_path() {
let handler = ProductionExtensionHandler;
let mut model = Model::new();
let mut obj = Object::new(1);
obj.production = Some(ProductionInfo {
uuid: Some("test-uuid".to_string()),
path: Some("relative/path.model".to_string()),
});
model.resources.objects.push(obj);
assert!(handler.validate(&model).is_err());
}
#[test]
fn test_post_parse_default() {
let handler = ProductionExtensionHandler;
let mut model = Model::new();
assert!(handler.post_parse(&mut model).is_ok());
}
#[test]
fn test_pre_write_default() {
let handler = ProductionExtensionHandler;
let mut model = Model::new();
assert!(handler.pre_write(&mut model).is_ok());
}
}