commit 7f12199f569d7b218379d2bbdd087804e9d5bd85
parent 5a293e9fb39a06f1a25acee36039f6242e702294
Author: Gavin Peacock <gpeacock@adobe.com>
Date: Fri, 17 Jun 2022 09:55:36 -0700
(MINOR) Clean up client example; update actions and schema (#51)
cleanup client-example - update actions & schema
Diffstat:
3 files changed, 46 insertions(+), 39 deletions(-)
diff --git a/sdk/examples/client/client.rs b/sdk/examples/client/client.rs
@@ -16,7 +16,7 @@
use anyhow::Result;
use c2pa::{
- assertions::{c2pa_action, labels, Action, Actions, CreativeWork},
+ assertions::{c2pa_action, labels, Action, Actions, CreativeWork, SchemaDotOrgPerson},
get_temp_signer, Ingredient, Manifest, ManifestStore,
};
use std::path::PathBuf;
@@ -29,8 +29,6 @@ fn fixture_path(file_name: &str) -> PathBuf {
}
const GENERATOR: &str = "test_app/0.1";
-const CREATIVE_WORK_URL: &str = r#"{"@type":"CreativeWork","@context":"https://schema.org","url":"http://contentauthenticity.org"}"#;
-
const INDENT_SPACE: usize = 2;
// Example for reading the contents of a manifest store, recursively showing nested manifests
@@ -87,32 +85,37 @@ fn show_manifest(manifest_store: &ManifestStore, manifest_label: &str, level: us
pub fn main() -> Result<()> {
let args: Vec<String> = std::env::args().collect();
- if args.len() != 3 {
- println!("This requires a path to a source image and a path to an output file. Both must be jpg or png files.");
- return Ok(());
- }
- let source = PathBuf::from(&args[1]);
- let dest = PathBuf::from(&args[2]);
-
- // create a new Manifest
- let mut manifest = Manifest::new(GENERATOR.to_owned());
+ // allow passing in source and dest paths or use defaults
+ let (src, dst) = match args.len() >= 3 {
+ true => (args[1].as_str(), args[2].as_str()),
+ false => (
+ "sdk/tests/fixtures/earth_apollo17.jpg",
+ "target/tmp/client.jpg",
+ ),
+ };
+ let source = PathBuf::from(src);
+ let dest = PathBuf::from(dst);
// if a filepath was provided on the command line, read it as a parent file
- let parent = Ingredient::from_file(source)?;
- let source = PathBuf::from(&args[1]);
+ let parent = Ingredient::from_file(source.as_path())?;
// create an action assertion stating that we imported this file
let actions = Actions::new().add_action(
Action::new(c2pa_action::PLACED)
- .set_parameter("identifier".to_owned(), parent.instance_id().to_owned())?,
+ .set_parameter("identifier", parent.instance_id().to_owned())?,
);
- manifest.add_assertion(&actions)?;
- // set the parent ingredient
- manifest.set_parent(parent)?;
+ // build a creative work assertion
+ let creative_work =
+ CreativeWork::new().add_author(SchemaDotOrgPerson::new().set_name("me")?)?;
- let creative_work = CreativeWork::from_json_str(CREATIVE_WORK_URL)?;
- manifest.add_assertion(&creative_work)?;
+ // create a new Manifest
+ let mut manifest = Manifest::new(GENERATOR.to_owned());
+ // add parent and assertions
+ manifest
+ .set_parent(parent)?
+ .add_assertion(&actions)?
+ .add_assertion(&creative_work)?;
// sign and embed into the target file
let cert_dir = fixture_path("certs");
diff --git a/sdk/src/assertions/actions.rs b/sdk/src/assertions/actions.rs
@@ -165,14 +165,14 @@ impl Action {
/// Sets the timestamp for when the action occurred.
///
/// This timestamp must be in ISO-8601 date.
- pub fn set_when(mut self, when: &str) -> Self {
- self.when = Some(when.to_owned());
+ pub fn set_when<S: Into<String>>(mut self, when: S) -> Self {
+ self.when = Some(when.into());
self
}
/// Sets the software agent that performed the action.
- pub fn set_software_agent(mut self, software_agent: &str) -> Self {
- self.software_agent = Some(software_agent.to_owned());
+ pub fn set_software_agent<S: Into<String>>(mut self, software_agent: S) -> Self {
+ self.software_agent = Some(software_agent.into());
self
}
@@ -185,24 +185,28 @@ impl Action {
/// Sets the value of the `xmpMM:InstanceID` property for the
/// modified (output) resource.
- pub fn set_instance_id(mut self, id: &str) -> Self {
- self.instance_id = Some(id.to_owned());
+ pub fn set_instance_id<S: Into<String>>(mut self, id: S) -> Self {
+ self.instance_id = Some(id.into());
self
}
/// Sets the additional parameters for this action.
///
/// These vary by the type of action.
- pub fn set_parameter<T: Serialize>(mut self, key: String, value: T) -> Result<Self> {
+ pub fn set_parameter<S: Into<String>, T: Serialize>(
+ mut self,
+ key: S,
+ value: T,
+ ) -> Result<Self> {
let value = serde_json::to_value(value).map_err(|_| Error::AssertionEncoding)?;
self.parameters = Some(match self.parameters {
Some(mut parameters) => {
- parameters.insert(key, value);
+ parameters.insert(key.into(), value);
parameters
}
None => {
let mut p = HashMap::new();
- p.insert(key, value);
+ p.insert(key.into(), value);
p
}
});
@@ -219,7 +223,7 @@ impl Action {
/// An `Actions` assertion provides information on edits and other
/// actions taken that affect the asset’s content.
///
-/// This assertion contains a list of [`Action`]s, each one declaring
+/// This assertion contains a list of [`Action`], each one declaring
/// what took place on the asset, when it took place, along with possible
/// other information such as what software performed the action.
///
diff --git a/sdk/src/assertions/schema_org.rs b/sdk/src/assertions/schema_org.rs
@@ -142,7 +142,7 @@ impl SchemaDotOrgPerson {
Self(SchemaDotOrg::new(Self::PERSON.to_owned()))
}
- pub fn new_person(name: String, identifier: String) -> Result<Self> {
+ pub fn new_person<S: Into<String>>(name: S, identifier: S) -> Result<Self> {
Self(SchemaDotOrg::new(Self::PERSON.to_owned()))
.set_name(name)?
.set_identifier(identifier)
@@ -154,16 +154,16 @@ impl SchemaDotOrgPerson {
}
/// insert key / value pair
- pub fn insert<T: Serialize>(self, key: String, value: T) -> Result<Self> {
- self.0.insert(key, value).map(Self)
+ pub fn insert<S: Into<String>, T: Serialize>(self, key: S, value: T) -> Result<Self> {
+ self.0.insert(key.into(), value).map(Self)
}
// add a value to a Vec stored at key
- pub fn insert_push<T>(self, key: String, value: T) -> Result<Self>
+ pub fn insert_push<S: Into<String>, T>(self, key: S, value: T) -> Result<Self>
where
T: Serialize + DeserializeOwned,
{
- self.0.insert_push(key, value).map(Self)
+ self.0.insert_push(key.into(), value).map(Self)
}
// get name field if it exists
@@ -171,8 +171,8 @@ impl SchemaDotOrgPerson {
self.get(Self::NAME)
}
- pub fn set_name(self, author: String) -> Result<Self> {
- self.insert(Self::NAME.to_owned(), author)
+ pub fn set_name<S: Into<String>>(self, author: S) -> Result<Self> {
+ self.insert(Self::NAME.to_string(), author.into())
}
// get identifier field if it exists
@@ -180,8 +180,8 @@ impl SchemaDotOrgPerson {
self.get(Self::IDENTIFIER)
}
- pub fn set_identifier(self, identifier: String) -> Result<Self> {
- self.insert(Self::IDENTIFIER.to_owned(), identifier)
+ pub fn set_identifier<S: Into<String>>(self, identifier: S) -> Result<Self> {
+ self.insert(Self::IDENTIFIER.to_owned(), identifier.into())
}
pub fn add_credential(self, credential: HashedUri) -> Result<Self> {