From e4dce311e7c04648fe94e1695873b72c88859d77 Mon Sep 17 00:00:00 2001 From: Gavin Peacock Date: Thu, 17 Oct 2024 15:19:56 -0700 Subject: [PATCH] fix: Adds identified RangeType to region of interest (#631) fix: Adds identified RangeType to region of interest. --- sdk/Cargo.toml | 2 +- sdk/src/assertions/actions.rs | 22 +++------------ sdk/src/assertions/metadata.rs | 11 ++------ sdk/src/assertions/region_of_interest.rs | 34 +++++++++++++++++------- sdk/src/builder.rs | 13 +++++++++ 5 files changed, 45 insertions(+), 37 deletions(-) diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index c04cd41ba..2396a4064 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -117,7 +117,7 @@ serde_bytes = "0.11.5" serde_cbor = "0.11.1" serde_derive = "1.0.197" serde_json = { version = "1.0.117", features = ["preserve_order"] } -serde_with = "3.4.0" +serde_with = "3.11.0" serde-transcode = "1.1.1" sha1 = "0.10.6" sha2 = "0.10.6" diff --git a/sdk/src/assertions/actions.rs b/sdk/src/assertions/actions.rs index f873846a9..518b05080 100644 --- a/sdk/src/assertions/actions.rs +++ b/sdk/src/assertions/actions.rs @@ -565,21 +565,14 @@ pub mod tests { .add_change(RegionOfInterest { region: vec![Range { range_type: RangeType::Temporal, - shape: None, time: Some(Time { time_type: TimeType::Npt, start: None, end: None, }), - frame: None, - text: None, + ..Default::default() }], - name: None, - identifier: None, - region_type: None, - role: None, - description: None, - metadata: None, + ..Default::default() }), ) .add_metadata( @@ -820,16 +813,9 @@ pub mod tests { description: Some("translated to klingon".to_owned()), region: vec![Range { range_type: RangeType::Temporal, - shape: None, - time: None, - frame: None, - text: None + ..Default::default() }], - name: None, - identifier: None, - region_type: None, - role: None, - metadata: None + ..Default::default() }] ); } diff --git a/sdk/src/assertions/metadata.rs b/sdk/src/assertions/metadata.rs index ef35a2a5e..95d84f157 100644 --- a/sdk/src/assertions/metadata.rs +++ b/sdk/src/assertions/metadata.rs @@ -326,21 +326,14 @@ pub mod tests { .set_region_of_interest(RegionOfInterest { region: vec![Range { range_type: RangeType::Temporal, - shape: None, time: Some(Time { time_type: TimeType::Npt, start: None, end: None, }), - frame: None, - text: None, + ..Default::default() }], - name: None, - identifier: None, - region_type: None, - role: None, - description: None, - metadata: None, + ..Default::default() }); original.insert("foo", test_value); println!("{:?}", &original); diff --git a/sdk/src/assertions/region_of_interest.rs b/sdk/src/assertions/region_of_interest.rs index 349299152..93ae9bc61 100644 --- a/sdk/src/assertions/region_of_interest.rs +++ b/sdk/src/assertions/region_of_interest.rs @@ -43,9 +43,9 @@ pub enum UnitType { } /// A spatial range representing rectangle, circle, or a polygon. +#[skip_serializing_none] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "json_schema", derive(JsonSchema))] -#[skip_serializing_none] pub struct Shape { /// The type of shape. #[serde(rename = "type")] @@ -83,9 +83,9 @@ pub enum TimeType { } /// A temporal range representing a starting time to an ending time. +#[skip_serializing_none] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "json_schema", derive(JsonSchema))] -#[skip_serializing_none] pub struct Time { /// The type of time. #[serde(rename = "type", default)] @@ -99,6 +99,7 @@ pub struct Time { /// A frame range representing starting and ending frames or pages. /// /// If both `start` and `end` are missing, the frame will span the entire asset. +#[skip_serializing_none] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "json_schema", derive(JsonSchema))] pub struct Frame { @@ -113,9 +114,9 @@ pub struct Frame { /// Selects a range of text via a fragment identifier. /// /// This is modeled after the W3C Web Annotation selector model. +#[skip_serializing_none] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "json_schema", derive(JsonSchema))] -#[skip_serializing_none] pub struct TextSelector { // TODO: can we provide more specific types? // @@ -128,9 +129,9 @@ pub struct TextSelector { } /// One or two [`TextSelector`][TextSelector] identifiying the range to select. +#[skip_serializing_none] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "json_schema", derive(JsonSchema))] -#[skip_serializing_none] pub struct TextSelectorRange { /// The start (or entire) text range. pub selector: TextSelector, @@ -146,27 +147,40 @@ pub struct Text { pub selectors: Vec, } -/// The type of range for the region of interest. +/// Description of the boundaries of an identified range. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "json_schema", derive(JsonSchema))] +pub struct Item { + /// The container-specific term used to identify items, such as "track_id" for MP4 or "item_ID" for HEIF. + pub identifier: String, + /// The value of the identifier, e.g. a value of "2" for an identifier of "track_id" would imply track 2 of the asset. + pub value: String, +} + +/// The type of range for the region of interest. +#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "json_schema", derive(JsonSchema))] #[serde(rename_all = "camelCase")] pub enum RangeType { /// A spatial range, see [`Shape`] for more details. Spatial, /// A temporal range, see [`Time`] for more details. + #[default] Temporal, /// A spatial range, see [`Frame`] for more details. Frame, /// A textual range, see [`Text`] for more details. Textual, + /// A range identified by a specific identifier and value, see [`Item`] for more details. + Identified, } // TODO: this can be much more idiomatic with an enum, but then it wouldn't line up with spec // /// A spatial, temporal, frame, or textual range describing the region of interest. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[cfg_attr(feature = "json_schema", derive(JsonSchema))] #[skip_serializing_none] +#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "json_schema", derive(JsonSchema))] pub struct Range { /// The type of range of interest. #[serde(rename = "type")] @@ -179,6 +193,8 @@ pub struct Range { pub frame: Option, /// A textual range. pub text: Option, + /// A item identifier. + pub item: Option, } /// A role describing the region. @@ -219,9 +235,9 @@ pub enum Role { /// /// This struct can be used from [`Action::changes`][crate::assertions::Action::changes] or /// [`Metadata::region_of_interest`][crate::assertions::Metadata::region_of_interest]. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[cfg_attr(feature = "json_schema", derive(JsonSchema))] #[skip_serializing_none] +#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "json_schema", derive(JsonSchema))] pub struct RegionOfInterest { /// A range describing the region of interest for the specific asset. pub region: Vec, diff --git a/sdk/src/builder.rs b/sdk/src/builder.rs index 2df49096d..f7e67ca04 100644 --- a/sdk/src/builder.rs +++ b/sdk/src/builder.rs @@ -1641,6 +1641,12 @@ mod tests { "identifier": "sample1.svg" }, "something": "else" + } + }, + { + "action": "c2pa.dubbed", + "softwareAgent": { + "name": "Test Dubber" }, "changes": [ { @@ -1648,6 +1654,13 @@ mod tests { { "type" : "temporal", "time" : {} + }, + { + "type": "identified", + "item": { + "identifier": "https://bioportal.bioontology.org/ontologies/FMA", + "value": "lips" + } } ], "description": "lip synced area"