commit ff7ba4791ca09a62ae061d7364d9f7dc8f955111
parent 779316a3e20212ae1674e3bd6eb46a8de4330773
Author: Gavin Peacock <gpeacock@adobe.com>
Date: Fri, 27 May 2022 10:25:11 -0700
Make Assertions opaque in the public SDK (#22)
Make Assertion opaque to the public SDK
all methods crate private
AssertionDecodeResult wrapped in Result outside of assertion.rs
Diffstat:
13 files changed, 95 insertions(+), 84 deletions(-)
diff --git a/sdk/examples/custom_assertion.rs b/sdk/examples/custom_assertion.rs
@@ -13,7 +13,7 @@
//! Example: Creating a custom assertion
//!
-use c2pa::{Assertion, AssertionBase, AssertionCbor, AssertionDecodeResult, Manifest, Result};
+use c2pa::{Assertion, AssertionBase, AssertionCbor, Manifest, Result};
use serde::{Deserialize, Serialize};
/// Defines a Custom assertion
@@ -54,7 +54,7 @@ impl AssertionBase for Custom {
Self::to_cbor_assertion(self)
}
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_assertion(assertion: &Assertion) -> Result<Self> {
Self::from_cbor_assertion(assertion)
}
}
diff --git a/sdk/src/assertion.rs b/sdk/src/assertion.rs
@@ -119,7 +119,7 @@ where
fn to_assertion(&self) -> Result<Assertion>;
/// Returns Self or AssertionDecode Result from an assertion
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self>;
+ fn from_assertion(assertion: &Assertion) -> Result<Self>;
}
/// Trait to handle default Cbor encoding/decoding of Assertions
@@ -130,16 +130,20 @@ pub trait AssertionCbor: Serialize + DeserializeOwned + AssertionBase {
Ok(Assertion::new(self.label(), Self::VERSION, data))
}
- fn from_cbor_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_cbor_assertion(assertion: &Assertion) -> Result<Self> {
assertion.check_max_version(Self::VERSION)?;
match assertion.decode_data() {
- AssertionData::Cbor(data) => Ok(serde_cbor::from_slice(data)
- .map_err(|e| AssertionDecodeError::from_assertion_and_cbor_err(assertion, e))?),
+ AssertionData::Cbor(data) => Ok(serde_cbor::from_slice(data).map_err(|e| {
+ Error::AssertionDecoding(AssertionDecodeError::from_assertion_and_cbor_err(
+ assertion, e,
+ ))
+ })?),
data => Err(AssertionDecodeError::from_assertion_unexpected_data_type(
assertion, data, "cbor",
- )),
+ )
+ .into()),
}
}
}
@@ -153,14 +157,14 @@ pub trait AssertionJson: Serialize + DeserializeOwned + AssertionBase {
Ok(Assertion::new(self.label(), Self::VERSION, data).set_content_type("application/json"))
}
- fn from_json_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_json_assertion(assertion: &Assertion) -> Result<Self> {
assertion.check_max_version(Self::VERSION)?;
match assertion.decode_data() {
AssertionData::Json(data) => Ok(serde_json::from_str(data)
.map_err(|e| AssertionDecodeError::from_assertion_and_json_err(assertion, e))?),
- data => Err(AssertionDecodeError::from_assertion_unexpected_data_type(
- assertion, data, "json",
+ data => Err(Error::AssertionDecoding(
+ AssertionDecodeError::from_assertion_unexpected_data_type(assertion, data, "json"),
)),
}
}
@@ -217,7 +221,7 @@ pub struct Assertion {
}
impl Assertion {
- pub fn new(label: &str, version: Option<usize>, data: AssertionData) -> Self {
+ pub(crate) fn new(label: &str, version: Option<usize>, data: AssertionData) -> Self {
Self {
label: label.to_owned(),
version,
@@ -226,58 +230,58 @@ impl Assertion {
}
}
- pub fn set_content_type(mut self, content_type: &str) -> Self {
+ pub(crate) fn set_content_type(mut self, content_type: &str) -> Self {
self.content_type = content_type.to_owned();
self
}
/// return content_type for the the data enclosed in the Assertion
- pub fn content_type(&self) -> String {
+ pub(crate) fn content_type(&self) -> String {
self.content_type.clone()
}
- pub fn set_data(mut self, data: &AssertionData) -> Self {
- self.data = data.to_owned();
- self
- }
+ // pub(crate) fn set_data(mut self, data: &AssertionData) -> Self {
+ // self.data = data.to_owned();
+ // self
+ // }
// Return version string of known assertion if available
- pub fn get_ver(&self) -> Option<usize> {
+ pub(crate) fn get_ver(&self) -> Option<usize> {
self.version
}
- pub fn check_version(&self, max_version: usize) -> AssertionDecodeResult<()> {
- match self.version {
- Some(version) if version > max_version => Err(AssertionDecodeError {
- label: self.label.clone(),
- version: self.version,
- content_type: self.content_type.clone(),
- source: AssertionDecodeErrorCause::AssertionTooNew {
- max: max_version,
- found: version,
- },
- }),
- _ => Ok(()),
- }
- }
+ // pub fn check_version(&self, max_version: usize) -> AssertionDecodeResult<()> {
+ // match self.version {
+ // Some(version) if version > max_version => Err(AssertionDecodeError {
+ // label: self.label.clone(),
+ // version: self.version,
+ // content_type: self.content_type.clone(),
+ // source: AssertionDecodeErrorCause::AssertionTooNew {
+ // max: max_version,
+ // found: version,
+ // },
+ // }),
+ // _ => Ok(()),
+ // }
+ // }
/// Return a reference to the AssertionData bound to this Assertion
- pub fn decode_data(&self) -> &AssertionData {
+ pub(crate) fn decode_data(&self) -> &AssertionData {
&self.data
}
/// return mimetype for the the data enclosed in the Assertion
- pub fn mime_type(&self) -> String {
+ pub(crate) fn mime_type(&self) -> String {
self.content_type.clone()
}
/// Test to see if the Assertions are of the same variant
- pub fn assertions_eq(a: &Assertion, b: &Assertion) -> bool {
+ pub(crate) fn assertions_eq(a: &Assertion, b: &Assertion) -> bool {
a.label_root() == b.label_root()
}
/// Return the CAI label for this Assertion (no version)
- pub fn label_root(&self) -> String {
+ pub(crate) fn label_root(&self) -> String {
let label = get_mutable_label(&self.label).0;
// thumbnails need the image_type added
match get_thumbnail_image_type(&self.label).as_str() {
@@ -287,7 +291,7 @@ impl Assertion {
}
/// Return the CAI label for this Assertion with version string if available
- pub fn label(&self) -> String {
+ pub(crate) fn label(&self) -> String {
let base_label = self.label_root();
match self.get_ver() {
Some(v) => {
@@ -303,7 +307,7 @@ impl Assertion {
}
/// Return a reference to the data as a byte array
- pub fn data(&self) -> &[u8] {
+ pub(crate) fn data(&self) -> &[u8] {
// return bytes of the assertion data
match self.decode_data() {
AssertionData::Json(x) => x.as_bytes(), // json encoded data
@@ -314,7 +318,7 @@ impl Assertion {
/// Return assertion as serde_json Object
/// this may have loss of cbor structure if unsupported in conversion to json
- pub fn as_json_object(&self) -> AssertionDecodeResult<Value> {
+ pub(crate) fn as_json_object(&self) -> AssertionDecodeResult<Value> {
match self.decode_data() {
AssertionData::Json(x) => serde_json::from_str(x)
.map_err(|e| AssertionDecodeError::from_assertion_and_json_err(self, e)),
@@ -376,7 +380,7 @@ impl Assertion {
}
/// create an assertion from binary data
- pub fn from_data_binary(label: &str, mime_type: &str, binary_data: &[u8]) -> Assertion {
+ pub(crate) fn from_data_binary(label: &str, mime_type: &str, binary_data: &[u8]) -> Assertion {
Self::from_assertion_data(
label,
mime_type,
@@ -385,7 +389,7 @@ impl Assertion {
}
/// create an assertion from user binary data
- pub fn from_data_uuid(label: &str, uuid_str: &str, binary_data: &[u8]) -> Assertion {
+ pub(crate) fn from_data_uuid(label: &str, uuid_str: &str, binary_data: &[u8]) -> Assertion {
Self::from_assertion_data(
label,
"application/octet-stream",
@@ -393,7 +397,7 @@ impl Assertion {
)
}
- pub fn from_data_cbor(label: &str, binary_data: &[u8]) -> Assertion {
+ pub(crate) fn from_data_cbor(label: &str, binary_data: &[u8]) -> Assertion {
Self::from_assertion_data(
label,
"application/cbor",
@@ -401,7 +405,10 @@ impl Assertion {
)
}
- pub fn from_data_json(label: &str, binary_data: &[u8]) -> AssertionDecodeResult<Assertion> {
+ pub(crate) fn from_data_json(
+ label: &str,
+ binary_data: &[u8],
+ ) -> AssertionDecodeResult<Assertion> {
let json = String::from_utf8(binary_data.to_vec()).map_err(|_| AssertionDecodeError {
label: label.to_string(),
version: None, // TODO: Can we get this info?
@@ -417,7 +424,10 @@ impl Assertion {
}
// Check assertion label against a target label.
- pub fn check_version_from_label(&self, desired_version: usize) -> AssertionDecodeResult<()> {
+ pub(crate) fn check_version_from_label(
+ &self,
+ desired_version: usize,
+ ) -> AssertionDecodeResult<()> {
if let Some(base_version) = labels::version(&self.label) {
if desired_version > base_version {
return Err(AssertionDecodeError {
@@ -456,7 +466,7 @@ impl Assertion {
}
#[derive(Serialize, Deserialize, Debug)]
-pub struct JsonAssertionData {
+pub(crate) struct JsonAssertionData {
label: String,
data: Value,
is_cbor: bool,
@@ -594,7 +604,7 @@ pub enum AssertionDecodeErrorCause {
CborError(#[from] serde_cbor::Error),
}
-pub type AssertionDecodeResult<T> = std::result::Result<T, AssertionDecodeError>;
+pub(crate) type AssertionDecodeResult<T> = std::result::Result<T, AssertionDecodeError>;
#[cfg(test)]
pub mod tests {
diff --git a/sdk/src/assertions/actions.rs b/sdk/src/assertions/actions.rs
@@ -12,7 +12,7 @@
// each license.
use crate::{
- assertion::{Assertion, AssertionBase, AssertionCbor, AssertionDecodeResult},
+ assertion::{Assertion, AssertionBase, AssertionCbor},
assertions::{labels, Actor, Metadata},
error::Result,
Error,
@@ -188,7 +188,7 @@ impl AssertionBase for Actions {
Self::to_cbor_assertion(self)
}
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_assertion(assertion: &Assertion) -> Result<Self> {
Self::from_cbor_assertion(assertion)
}
}
diff --git a/sdk/src/assertions/creative_work.rs b/sdk/src/assertions/creative_work.rs
@@ -14,7 +14,7 @@
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::{
- assertion::{Assertion, AssertionBase, AssertionDecodeResult, AssertionJson},
+ assertion::{Assertion, AssertionBase, AssertionJson},
assertions::{labels, SchemaDotOrg, SchemaDotOrgPerson},
error::Result,
};
@@ -96,7 +96,7 @@ impl AssertionBase for CreativeWork {
Self::to_json_assertion(self)
}
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_assertion(assertion: &Assertion) -> Result<Self> {
Self::from_json_assertion(assertion)
}
}
diff --git a/sdk/src/assertions/data_hash.rs b/sdk/src/assertions/data_hash.rs
@@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf;
use crate::{
- assertion::{Assertion, AssertionBase, AssertionCbor, AssertionDecodeResult},
+ assertion::{Assertion, AssertionBase, AssertionCbor},
assertions::labels,
cbor_types::UriT,
error::{wrap_io_err, Error, Result},
@@ -199,7 +199,7 @@ impl DataHash {
}
/// Create a new instance from Assertion
- pub fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ pub fn from_assertion(assertion: &Assertion) -> Result<Self> {
assertion.check_version_from_label(ASSERTION_CREATION_VERSION)?;
Self::from_cbor_assertion(assertion)
}
@@ -220,7 +220,7 @@ impl AssertionBase for DataHash {
Self::to_cbor_assertion(self)
}
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_assertion(assertion: &Assertion) -> Result<Self> {
Self::from_cbor_assertion(assertion)
}
}
diff --git a/sdk/src/assertions/ingredient.rs b/sdk/src/assertions/ingredient.rs
@@ -14,7 +14,7 @@
use serde::{Deserialize, Serialize};
use crate::{
- assertion::{Assertion, AssertionBase, AssertionCbor, AssertionDecodeResult},
+ assertion::{Assertion, AssertionBase, AssertionCbor},
assertions::{labels, Metadata, ReviewRating},
error::Result,
hashed_uri::HashedUri,
@@ -141,7 +141,7 @@ impl AssertionBase for Ingredient {
Self::to_cbor_assertion(self)
}
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_assertion(assertion: &Assertion) -> Result<Self> {
Self::from_cbor_assertion(assertion)
}
}
diff --git a/sdk/src/assertions/metadata.rs b/sdk/src/assertions/metadata.rs
@@ -12,7 +12,7 @@
// each license.
use crate::{
- assertion::{Assertion, AssertionBase, AssertionCbor, AssertionDecodeResult},
+ assertion::{Assertion, AssertionBase, AssertionCbor},
assertions::labels,
error::Result,
hashed_uri::HashedUri,
@@ -111,7 +111,7 @@ impl AssertionBase for Metadata {
Self::to_cbor_assertion(self)
}
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_assertion(assertion: &Assertion) -> Result<Self> {
Self::from_cbor_assertion(assertion)
}
}
diff --git a/sdk/src/assertions/schema_org.rs b/sdk/src/assertions/schema_org.rs
@@ -14,7 +14,7 @@
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::{
- assertion::{Assertion, AssertionBase, AssertionDecodeResult, AssertionJson},
+ assertion::{Assertion, AssertionBase, AssertionJson},
assertions::labels,
error::{Error, Result},
hashed_uri::HashedUri,
@@ -125,7 +125,7 @@ impl AssertionBase for SchemaDotOrg {
Self::to_json_assertion(self)
}
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_assertion(assertion: &Assertion) -> Result<Self> {
Self::from_json_assertion(assertion)
}
}
diff --git a/sdk/src/assertions/thumbnail.rs b/sdk/src/assertions/thumbnail.rs
@@ -14,7 +14,6 @@
use crate::{
assertion::{
get_thumbnail_image_type, Assertion, AssertionBase, AssertionData, AssertionDecodeError,
- AssertionDecodeResult,
},
assertions::labels,
error::Result,
@@ -68,7 +67,7 @@ impl AssertionBase for Thumbnail {
Ok(Assertion::new(&self.label, None, data).set_content_type(&self.content_type))
}
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Thumbnail> {
+ fn from_assertion(assertion: &Assertion) -> Result<Thumbnail> {
match assertion.decode_data() {
AssertionData::Binary(data) => Ok(Self {
data: data.to_owned(),
@@ -77,7 +76,8 @@ impl AssertionBase for Thumbnail {
}),
ad => Err(AssertionDecodeError::from_assertion_unexpected_data_type(
assertion, ad, "binary",
- )),
+ )
+ .into()),
}
}
}
diff --git a/sdk/src/assertions/user.rs b/sdk/src/assertions/user.rs
@@ -12,9 +12,7 @@
// each license.
use crate::{
- assertion::{
- Assertion, AssertionBase, AssertionData, AssertionDecodeError, AssertionDecodeResult,
- },
+ assertion::{Assertion, AssertionBase, AssertionData, AssertionDecodeError},
error::{Error, Result},
};
use serde::Serialize;
@@ -51,18 +49,22 @@ impl AssertionBase for User {
Ok(Assertion::new(&self.label, None, data).set_content_type("application/json"))
}
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_assertion(assertion: &Assertion) -> Result<Self> {
match assertion.decode_data() {
AssertionData::Json(data) => {
// validate that the data is valid json, but do not modify it if valid
- let _value: serde_json::Value = serde_json::from_str(data)
- .map_err(|e| AssertionDecodeError::from_assertion_and_json_err(assertion, e))?;
+ let _value: serde_json::Value = serde_json::from_str(data).map_err(|e| {
+ Error::AssertionDecoding(AssertionDecodeError::from_assertion_and_json_err(
+ assertion, e,
+ ))
+ })?;
Ok(User::new(&assertion.label(), data))
}
ad => Err(AssertionDecodeError::from_assertion_unexpected_data_type(
assertion, ad, "json",
- )),
+ )
+ .into()),
}
}
}
diff --git a/sdk/src/assertions/user_cbor.rs b/sdk/src/assertions/user_cbor.rs
@@ -14,9 +14,7 @@
use serde::{Deserialize, Serialize};
use crate::{
- assertion::{
- Assertion, AssertionBase, AssertionData, AssertionDecodeError, AssertionDecodeResult,
- },
+ assertion::{Assertion, AssertionBase, AssertionData, AssertionDecodeError},
error::{Error, Result},
};
@@ -51,18 +49,22 @@ impl AssertionBase for UserCbor {
Ok(Assertion::new(&self.label, None, data))
}
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_assertion(assertion: &Assertion) -> Result<Self> {
match assertion.decode_data() {
AssertionData::Cbor(data) => {
// validate cbor
- let _value: serde_cbor::Value = serde_cbor::from_slice(data)
- .map_err(|e| AssertionDecodeError::from_assertion_and_cbor_err(assertion, e))?;
+ let _value: serde_cbor::Value = serde_cbor::from_slice(data).map_err(|e| {
+ Error::AssertionDecoding(AssertionDecodeError::from_assertion_and_cbor_err(
+ assertion, e,
+ ))
+ })?;
Ok(Self::new(&assertion.label(), data.clone()))
}
ad => Err(AssertionDecodeError::from_assertion_unexpected_data_type(
assertion, ad, "cbor",
- )),
+ )
+ .into()),
}
}
}
diff --git a/sdk/src/assertions/uuid_assertion.rs b/sdk/src/assertions/uuid_assertion.rs
@@ -12,9 +12,7 @@
// each license.
use crate::{
- assertion::{
- Assertion, AssertionBase, AssertionData, AssertionDecodeError, AssertionDecodeResult,
- },
+ assertion::{Assertion, AssertionBase, AssertionData, AssertionDecodeError},
error::{Error, Result},
};
@@ -56,14 +54,15 @@ impl AssertionBase for Uuid {
Ok(Assertion::new(&self.label, None, data).set_content_type("application/octet-stream"))
}
- fn from_assertion(assertion: &Assertion) -> AssertionDecodeResult<Self> {
+ fn from_assertion(assertion: &Assertion) -> Result<Self> {
match assertion.decode_data() {
AssertionData::Uuid(s, data) => {
Ok(Uuid::new(&assertion.label(), s.clone(), data.clone()))
}
ad => Err(AssertionDecodeError::from_assertion_unexpected_data_type(
assertion, ad, "uuid",
- )),
+ )
+ .into()),
}
}
}
diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs
@@ -66,9 +66,7 @@
//! # }
//! ```
-pub use assertion::{
- Assertion, AssertionBase, AssertionCbor, AssertionDecodeResult, AssertionJson,
-};
+pub use assertion::{Assertion, AssertionBase, AssertionCbor, AssertionJson};
pub mod assertions;
mod cose_validator;