use crate::error::{Error, Result};
use crate::storage::traits::ManifestType;
use atlas_c2pa_lib::assertion::Assertion;
use atlas_c2pa_lib::asset_type::AssetType;
use atlas_c2pa_lib::manifest::Manifest;
use std::path::Path;
pub fn determine_model_type(path: &Path) -> Result<AssetType> {
match path.extension().and_then(|ext| ext.to_str()) {
Some("pb") | Some("savedmodel") | Some("tf") => Ok(AssetType::ModelTensorFlow),
Some("pt") | Some("pth") | Some("pytorch") => Ok(AssetType::ModelPytorch),
Some("onnx") => Ok(AssetType::ModelOnnx),
Some("bin") | Some("xml") => Ok(AssetType::ModelOpenVino),
Some("h5") | Some("keras") | Some("hdf5") => Ok(AssetType::ModelKeras),
Some("jax") => Ok(AssetType::ModelJax),
Some("mlnet") | Some("zip") => Ok(AssetType::ModelMlNet),
Some("params") | Some("json") | Some("mxnet") => Ok(AssetType::ModelMxNet),
Some("npy") | Some("npz") => Ok(AssetType::FormatNumpy),
Some("protobuf") | Some("proto") => Ok(AssetType::FormatProtobuf),
Some("pkl") | Some("pickle") => Ok(AssetType::FormatPickle),
Some(_) => Ok(AssetType::Model),
None => Err(Error::Validation(
"Unsupported model format: file has no extension".to_string(),
)),
}
}
pub fn determine_format(path: &Path) -> Result<String> {
match path.extension().and_then(|ext| ext.to_str()) {
Some("pb") => Ok("application/x-protobuf".to_string()),
Some("savedmodel") | Some("tf") => Ok("application/x-tensorflow".to_string()),
Some("pt") | Some("pth") | Some("pytorch") => Ok("application/x-pytorch".to_string()),
Some("onnx") => Ok("application/onnx".to_string()),
Some("bin") | Some("xml") => Ok("application/x-openvino".to_string()),
Some("h5") | Some("keras") | Some("hdf5") => Ok("application/x-hdf5".to_string()),
Some("jax") => Ok("application/x-jax".to_string()),
Some("mlnet") => Ok("application/x-mlnet".to_string()),
Some("zip") => Ok("application/zip".to_string()),
Some("params") | Some("mxnet") => Ok("application/x-mxnet".to_string()),
Some("json") => Ok("application/json".to_string()),
Some("npy") | Some("npz") => Ok("application/x-numpy".to_string()),
Some("protobuf") | Some("proto") => Ok("application/x-protobuf".to_string()),
Some("pkl") | Some("pickle") => Ok("application/x-pickle".to_string()),
_ => Ok("application/octet-stream".to_string()),
}
}
pub fn determine_software_type(path: &Path) -> Result<AssetType> {
match path.extension().and_then(|ext| ext.to_str()) {
Some("py") => Ok(AssetType::Generator), Some("ipynb") => Ok(AssetType::Generator), Some("r") => Ok(AssetType::Generator), Some("jl") => Ok(AssetType::Generator),
Some("dockerfile") | Some("Dockerfile") => Ok(AssetType::Generator), Some("yaml") | Some("yml") => Ok(AssetType::Generator), Some("toml") => Ok(AssetType::Generator), Some("json") => Ok(AssetType::Generator),
Some("pbtxt") => Ok(AssetType::Generator), Some("prototxt") => Ok(AssetType::Generator),
Some("rs") => Ok(AssetType::Generator), Some("cpp") | Some("cc") | Some("cxx") => Ok(AssetType::Generator), Some("cu") | Some("cuh") => Ok(AssetType::Generator),
Some("sh") => Ok(AssetType::Generator), Some("bash") => Ok(AssetType::Generator),
Some("sql") => Ok(AssetType::Generator),
Some("vmx") | Some("ovf") | Some("ova") => Ok(AssetType::Generator),
_ => Ok(AssetType::Generator),
}
}
pub fn determine_dataset_type(path: &Path) -> Result<AssetType> {
match path.extension().and_then(|ext| ext.to_str()) {
Some("csv") | Some("tsv") | Some("txt") => Ok(AssetType::Dataset),
Some("json") | Some("jsonl") => Ok(AssetType::Dataset),
Some("parquet") | Some("orc") | Some("avro") => Ok(AssetType::Dataset),
Some("tfrecord") | Some("tfrec") => Ok(AssetType::DatasetTensorFlow),
Some("pb") | Some("proto") | Some("tf") => Ok(AssetType::DatasetTensorFlow),
Some("pt") | Some("pth") | Some("pytorch") => Ok(AssetType::DatasetPytorch),
Some("onnx") => Ok(AssetType::DatasetOnnx),
Some("bin") | Some("xml") => Ok(AssetType::DatasetOpenVino),
Some("h5") | Some("hdf5") | Some("keras") => Ok(AssetType::DatasetKeras),
Some("jax") => Ok(AssetType::DatasetJax),
Some("mlnet") | Some("zip") => Ok(AssetType::DatasetMlNet),
Some("rec") | Some("idx") | Some("params") | Some("lst") | Some("mxnet") => {
Ok(AssetType::DatasetMxNet)
}
Some("npy") | Some("npz") => Ok(AssetType::Dataset),
Some("pkl") | Some("pickle") => Ok(AssetType::Dataset),
Some("jpg") | Some("jpeg") | Some("png") | Some("bmp") | Some("tiff") => {
Ok(AssetType::Dataset)
}
Some(_) => Ok(AssetType::Dataset),
None => Err(Error::Validation(
"Unsupported dataset format: file has no extension".to_string(),
)),
}
}
pub fn determine_manifest_type(manifest: &Manifest) -> ManifestType {
let has_dataset_assertion = (if let Some(claim) = &manifest.claim_v2 {
claim.created_assertions.iter().any(|assertion| {
if let Assertion::CreativeWork(creative_work) = assertion {
creative_work.creative_type == "Dataset"
} else {
false
}
})
} else {
false
}) || manifest.claim.created_assertions.iter().any(|assertion| {
if let Assertion::CreativeWork(creative_work) = assertion {
creative_work.creative_type == "Dataset"
} else {
false
}
});
let has_dataset_ingredients = manifest.ingredients.iter().any(|ingredient| {
ingredient.data.data_types.iter().any(|t| {
matches!(
t,
AssetType::Dataset
| AssetType::DatasetOnnx
| AssetType::DatasetTensorFlow
| AssetType::DatasetPytorch
)
})
});
if has_dataset_assertion || has_dataset_ingredients {
return ManifestType::Dataset;
}
let has_software_assertion = (if let Some(claim) = &manifest.claim_v2 {
claim.created_assertions.iter().any(|assertion| {
if let Assertion::CreativeWork(creative_work) = assertion {
creative_work.creative_type == "Software"
} else {
false
}
})
} else {
false
}) || manifest.claim.created_assertions.iter().any(|assertion| {
if let Assertion::CreativeWork(creative_work) = assertion {
creative_work.creative_type == "Software"
} else {
false
}
});
let has_software_parameters = (if let Some(claim) = &manifest.claim_v2 {
claim.created_assertions.iter().any(|assertion| {
if let Assertion::Action(action_assertion) = assertion {
action_assertion.actions.iter().any(|action| {
if let Some(params) = &action.parameters {
params.get("software_type").is_some()
} else {
false
}
})
} else {
false
}
})
} else {
false
}) || manifest.claim.created_assertions.iter().any(|assertion| {
if let Assertion::Action(action_assertion) = assertion {
action_assertion.actions.iter().any(|action| {
if let Some(params) = &action.parameters {
params.get("software_type").is_some()
} else {
false
}
})
} else {
false
}
});
let has_software_ingredients = manifest.ingredients.iter().any(|ingredient| {
ingredient
.data
.data_types
.iter()
.any(|t| matches!(t, AssetType::Generator))
});
if has_software_assertion || has_software_parameters || has_software_ingredients {
return ManifestType::Software;
}
let has_model_assertion = (if let Some(claim) = &manifest.claim_v2 {
claim.created_assertions.iter().any(|assertion| {
if let Assertion::CreativeWork(creative_work) = assertion {
creative_work.creative_type == "Model"
} else {
false
}
})
} else {
false
}) || manifest.claim.created_assertions.iter().any(|assertion| {
if let Assertion::CreativeWork(creative_work) = assertion {
creative_work.creative_type == "Model"
} else {
false
}
});
let has_model_ingredients = manifest.ingredients.iter().any(|ingredient| {
ingredient.data.data_types.iter().any(|t| {
matches!(
t,
AssetType::Model
| AssetType::ModelOnnx
| AssetType::ModelTensorFlow
| AssetType::ModelPytorch
| AssetType::ModelOpenVino
)
})
});
if has_model_assertion || has_model_ingredients {
return ManifestType::Model;
}
ManifestType::Unknown
}
pub fn manifest_type_to_string(manifest_type: &ManifestType) -> String {
manifest_type.to_string()
}
pub fn manifest_type_to_str(manifest_type: &ManifestType) -> &'static str {
match manifest_type {
ManifestType::Dataset => "Dataset",
ManifestType::Model => "Model",
ManifestType::Software => "Software",
ManifestType::Unknown => "Unknown",
}
}
pub fn parse_manifest_type(type_str: &str) -> ManifestType {
match type_str.to_lowercase().as_str() {
"dataset" => ManifestType::Dataset,
"software" => ManifestType::Software,
_ => ManifestType::Model, }
}
#[cfg(test)]
mod tests {
use super::*;
use crate::error::Result;
use atlas_c2pa_lib::assertion::{Assertion, Author, CreativeWorkAssertion};
use atlas_c2pa_lib::asset_type::AssetType;
use atlas_c2pa_lib::manifest::Manifest;
use std::path::PathBuf;
#[test]
fn test_determine_model_type() -> Result<()> {
assert_eq!(
determine_model_type(&PathBuf::from("model.pb"))?,
AssetType::ModelTensorFlow
);
assert_eq!(
determine_model_type(&PathBuf::from("model.savedmodel"))?,
AssetType::ModelTensorFlow
);
assert_eq!(
determine_model_type(&PathBuf::from("model.tf"))?,
AssetType::ModelTensorFlow
);
assert_eq!(
determine_model_type(&PathBuf::from("model.pt"))?,
AssetType::ModelPytorch
);
assert_eq!(
determine_model_type(&PathBuf::from("model.pth"))?,
AssetType::ModelPytorch
);
assert_eq!(
determine_model_type(&PathBuf::from("model.pytorch"))?,
AssetType::ModelPytorch
);
assert_eq!(
determine_model_type(&PathBuf::from("model.onnx"))?,
AssetType::ModelOnnx
);
assert_eq!(
determine_model_type(&PathBuf::from("model.bin"))?,
AssetType::ModelOpenVino
);
assert_eq!(
determine_model_type(&PathBuf::from("model.xml"))?,
AssetType::ModelOpenVino
);
assert_eq!(
determine_model_type(&PathBuf::from("model.h5"))?,
AssetType::ModelKeras
);
assert_eq!(
determine_model_type(&PathBuf::from("model.keras"))?,
AssetType::ModelKeras
);
assert_eq!(
determine_model_type(&PathBuf::from("model.hdf5"))?,
AssetType::ModelKeras
);
assert_eq!(
determine_model_type(&PathBuf::from("model.jax"))?,
AssetType::ModelJax
);
assert_eq!(
determine_model_type(&PathBuf::from("model.mlnet"))?,
AssetType::ModelMlNet
);
assert_eq!(
determine_model_type(&PathBuf::from("model.zip"))?,
AssetType::ModelMlNet
);
assert_eq!(
determine_model_type(&PathBuf::from("model.params"))?,
AssetType::ModelMxNet
);
assert_eq!(
determine_model_type(&PathBuf::from("model.json"))?,
AssetType::ModelMxNet
);
assert_eq!(
determine_model_type(&PathBuf::from("model.mxnet"))?,
AssetType::ModelMxNet
);
assert_eq!(
determine_model_type(&PathBuf::from("model.npy"))?,
AssetType::FormatNumpy
);
assert_eq!(
determine_model_type(&PathBuf::from("model.npz"))?,
AssetType::FormatNumpy
);
assert_eq!(
determine_model_type(&PathBuf::from("model.protobuf"))?,
AssetType::FormatProtobuf
);
assert_eq!(
determine_model_type(&PathBuf::from("model.proto"))?,
AssetType::FormatProtobuf
);
assert_eq!(
determine_model_type(&PathBuf::from("model.pkl"))?,
AssetType::FormatPickle
);
assert_eq!(
determine_model_type(&PathBuf::from("model.pickle"))?,
AssetType::FormatPickle
);
assert_eq!(
determine_model_type(&PathBuf::from("model.unknown"))?,
AssetType::Model
);
let result = determine_model_type(&PathBuf::from("model"));
assert!(result.is_err());
Ok(())
}
#[test]
fn test_determine_format() -> Result<()> {
assert_eq!(
determine_format(&PathBuf::from("model.pb"))?,
"application/x-protobuf"
);
assert_eq!(
determine_format(&PathBuf::from("model.savedmodel"))?,
"application/x-tensorflow"
);
assert_eq!(
determine_format(&PathBuf::from("model.tf"))?,
"application/x-tensorflow"
);
assert_eq!(
determine_format(&PathBuf::from("model.pt"))?,
"application/x-pytorch"
);
assert_eq!(
determine_format(&PathBuf::from("model.pth"))?,
"application/x-pytorch"
);
assert_eq!(
determine_format(&PathBuf::from("model.pytorch"))?,
"application/x-pytorch"
);
assert_eq!(
determine_format(&PathBuf::from("model.onnx"))?,
"application/onnx"
);
assert_eq!(
determine_format(&PathBuf::from("model.bin"))?,
"application/x-openvino"
);
assert_eq!(
determine_format(&PathBuf::from("model.xml"))?,
"application/x-openvino"
);
assert_eq!(
determine_format(&PathBuf::from("model.h5"))?,
"application/x-hdf5"
);
assert_eq!(
determine_format(&PathBuf::from("model.keras"))?,
"application/x-hdf5"
);
assert_eq!(
determine_format(&PathBuf::from("model.hdf5"))?,
"application/x-hdf5"
);
assert_eq!(
determine_format(&PathBuf::from("model.jax"))?,
"application/x-jax"
);
assert_eq!(
determine_format(&PathBuf::from("model.mlnet"))?,
"application/x-mlnet"
);
assert_eq!(
determine_format(&PathBuf::from("model.zip"))?,
"application/zip"
);
assert_eq!(
determine_format(&PathBuf::from("model.params"))?,
"application/x-mxnet"
);
assert_eq!(
determine_format(&PathBuf::from("model.json"))?,
"application/json"
);
assert_eq!(
determine_format(&PathBuf::from("model.mxnet"))?,
"application/x-mxnet"
);
assert_eq!(
determine_format(&PathBuf::from("model.npy"))?,
"application/x-numpy"
);
assert_eq!(
determine_format(&PathBuf::from("model.npz"))?,
"application/x-numpy"
);
assert_eq!(
determine_format(&PathBuf::from("model.protobuf"))?,
"application/x-protobuf"
);
assert_eq!(
determine_format(&PathBuf::from("model.proto"))?,
"application/x-protobuf"
);
assert_eq!(
determine_format(&PathBuf::from("model.pkl"))?,
"application/x-pickle"
);
assert_eq!(
determine_format(&PathBuf::from("model.pickle"))?,
"application/x-pickle"
);
assert_eq!(
determine_format(&PathBuf::from("model.unknown"))?,
"application/octet-stream"
);
assert_eq!(
determine_format(&PathBuf::from("model"))?,
"application/octet-stream"
);
Ok(())
}
#[test]
fn test_determine_software_type() -> Result<()> {
assert_eq!(
determine_software_type(&PathBuf::from("script.py"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("notebook.ipynb"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("analysis.r"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("compute.jl"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("Dockerfile"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("config.yaml"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("config.yml"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("pyproject.toml"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("config.json"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("model.pbtxt"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("model.prototxt"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("wrapper.rs"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("kernels.cpp"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("kernels.cc"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("algo.cu"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("build.sh"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("setup.bash"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("query.sql"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("config.vmx"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("template.ovf"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("image.ova"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("unknown.ext"))?,
AssetType::Generator
);
assert_eq!(
determine_software_type(&PathBuf::from("no_extension"))?,
AssetType::Generator
);
Ok(())
}
#[test]
fn test_determine_dataset_type() -> Result<()> {
assert_eq!(
determine_dataset_type(&PathBuf::from("data.csv"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.tsv"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.txt"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.json"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.jsonl"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.parquet"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.orc"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.avro"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.tfrecord"))?,
AssetType::DatasetTensorFlow
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.tfrec"))?,
AssetType::DatasetTensorFlow
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.pb"))?,
AssetType::DatasetTensorFlow
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.pt"))?,
AssetType::DatasetPytorch
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.pth"))?,
AssetType::DatasetPytorch
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.onnx"))?,
AssetType::DatasetOnnx
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.bin"))?,
AssetType::DatasetOpenVino
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.xml"))?,
AssetType::DatasetOpenVino
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.h5"))?,
AssetType::DatasetKeras
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.hdf5"))?,
AssetType::DatasetKeras
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.jax"))?,
AssetType::DatasetJax
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.mlnet"))?,
AssetType::DatasetMlNet
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.rec"))?,
AssetType::DatasetMxNet
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.idx"))?,
AssetType::DatasetMxNet
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.npy"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.npz"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.pkl"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.pickle"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("images.jpg"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("images.jpeg"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("images.png"))?,
AssetType::Dataset
);
assert_eq!(
determine_dataset_type(&PathBuf::from("data.unknown"))?,
AssetType::Dataset
);
let result = determine_dataset_type(&PathBuf::from("dataset"));
assert!(result.is_err());
Ok(())
}
#[test]
fn test_determine_manifest_type() {
let mut manifest = create_test_manifest();
manifest.ingredients[0].data.data_types = vec![AssetType::Dataset];
println!("DEBUG: Set ingredient data_type to Dataset");
let model_assertion = Assertion::CreativeWork(CreativeWorkAssertion {
context: "http://schema.org/".to_string(),
creative_type: "Model".to_string(),
author: vec![Author {
author_type: "Organization".to_string(),
name: "Test Org".to_string(),
}],
});
if let Some(claim) = &mut manifest.claim_v2 {
claim.created_assertions.clear();
claim.created_assertions.push(model_assertion.clone());
println!("DEBUG: Added Model assertion to claim_v2");
}
manifest.claim.created_assertions.clear();
manifest.claim.created_assertions.push(model_assertion);
println!("DEBUG: Added Model assertion to legacy claim");
let manifest_type = determine_manifest_type(&manifest);
assert_eq!(
manifest_type_to_str(&manifest_type),
"Dataset",
"Should detect Dataset from ingredients when there's no matching Dataset assertion"
);
}
#[test]
fn test_determine_manifest_type_with_action_parameters() {
let mut manifest = create_test_manifest();
manifest.ingredients[0].data.data_types = vec![AssetType::Model];
if let Some(claim) = &mut manifest.claim_v2 {
claim.created_assertions = vec![Assertion::Action(
atlas_c2pa_lib::assertion::ActionAssertion {
actions: vec![atlas_c2pa_lib::assertion::Action {
action: "c2pa.created".to_string(),
software_agent: Some("test_agent".to_string()),
parameters: Some(serde_json::json!({
"software_type": "container_image",
"version": "1.0.0"
})),
digital_source_type: Some(
"http://cv.iptc.org/newscodes/digitalsourcetype/software".to_string(),
),
instance_id: None,
}],
},
)];
}
manifest.claim.created_assertions = vec![Assertion::Action(
atlas_c2pa_lib::assertion::ActionAssertion {
actions: vec![atlas_c2pa_lib::assertion::Action {
action: "c2pa.created".to_string(),
software_agent: Some("test_agent".to_string()),
parameters: Some(serde_json::json!({
"software_type": "container_image",
"version": "1.0.0"
})),
digital_source_type: Some(
"http://cv.iptc.org/newscodes/digitalsourcetype/software".to_string(),
),
instance_id: None,
}],
},
)];
let manifest_type = determine_manifest_type(&manifest);
assert_eq!(manifest_type_to_str(&manifest_type), "Software");
}
#[test]
fn test_manifest_type_conversion() {
use crate::storage::traits::ManifestType;
assert_eq!(manifest_type_to_string(&ManifestType::Dataset), "Dataset");
assert_eq!(manifest_type_to_string(&ManifestType::Model), "Model");
assert_eq!(manifest_type_to_string(&ManifestType::Software), "Software");
assert_eq!(manifest_type_to_str(&ManifestType::Dataset), "Dataset");
assert_eq!(manifest_type_to_str(&ManifestType::Model), "Model");
assert_eq!(manifest_type_to_str(&ManifestType::Software), "Software");
assert_eq!(parse_manifest_type("dataset"), ManifestType::Dataset);
assert_eq!(parse_manifest_type("Dataset"), ManifestType::Dataset);
assert_eq!(parse_manifest_type("DATASET"), ManifestType::Dataset);
assert_eq!(parse_manifest_type("software"), ManifestType::Software);
assert_eq!(parse_manifest_type("Software"), ManifestType::Software);
assert_eq!(parse_manifest_type("SOFTWARE"), ManifestType::Software);
assert_eq!(parse_manifest_type("model"), ManifestType::Model);
assert_eq!(parse_manifest_type("unknown"), ManifestType::Model);
assert_eq!(parse_manifest_type(""), ManifestType::Model);
}
fn create_test_manifest() -> Manifest {
use atlas_c2pa_lib::claim::ClaimV2;
use atlas_c2pa_lib::datetime_wrapper::OffsetDateTimeWrapper;
use atlas_c2pa_lib::ingredient::{Ingredient, IngredientData};
use time::OffsetDateTime;
use uuid::Uuid;
let ingredient = Ingredient {
title: "Test Ingredient".to_string(),
format: "application/octet-stream".to_string(),
relationship: "componentOf".to_string(),
document_id: format!("uuid:{}", Uuid::new_v4()),
instance_id: format!("uuid:{}", Uuid::new_v4()),
data: IngredientData {
url: "file:///test/path.bin".to_string(),
alg: "sha256".to_string(),
hash: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
.to_string(),
data_types: vec![AssetType::Model],
linked_ingredient_url: None,
linked_ingredient_hash: None,
},
linked_ingredient: None,
public_key: None,
};
let claim = ClaimV2 {
instance_id: format!("urn:uuid:{}", Uuid::new_v4()),
claim_generator_info: "test".to_string(),
created_at: OffsetDateTimeWrapper(OffsetDateTime::now_utc()),
ingredients: vec![ingredient.clone()],
created_assertions: vec![Assertion::CreativeWork(CreativeWorkAssertion {
context: "http://schema.org/".to_string(),
creative_type: "Model".to_string(),
author: vec![Author {
author_type: "Organization".to_string(),
name: "Test Organization".to_string(),
}],
})],
signature: None,
};
Manifest {
claim_generator: "test".to_string(),
title: "Test Manifest".to_string(),
instance_id: format!("urn:uuid:{}", Uuid::new_v4()),
ingredients: vec![ingredient],
claim: claim.clone(),
created_at: OffsetDateTimeWrapper(OffsetDateTime::now_utc()),
cross_references: vec![],
claim_v2: Some(claim),
is_active: true,
}
}
}