c2pa-rs

A fork of https://github.com/contentauth/c2pa-rs/
git clone git://archive.git.mtrnord.blog/mtrnords-photography-manager/c2pa-rs.git
Log | Files | Refs | README

claim_generator_info.rs (4167B)


      1 // Copyright 2023 Adobe. All rights reserved.
      2 // This file is licensed to you under the Apache License,
      3 // Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
      4 // or the MIT license (http://opensource.org/licenses/MIT),
      5 // at your option.
      6 
      7 // Unless required by applicable law or agreed to in writing,
      8 // this software is distributed on an "AS IS" BASIS, WITHOUT
      9 // WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
     10 // implied. See the LICENSE-MIT and LICENSE-APACHE files for the
     11 // specific language governing permissions and limitations under
     12 
     13 // each license.
     14 use std::collections::HashMap;
     15 
     16 #[cfg(feature = "json_schema")]
     17 use schemars::JsonSchema;
     18 use serde::{Deserialize, Serialize};
     19 use serde_json::Value;
     20 
     21 use crate::resource_store::UriOrResource;
     22 
     23 /// Description of the claim generator, or the software used in generating the claim.
     24 ///
     25 /// This structure is also used for actions softwareAgent
     26 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
     27 #[cfg_attr(feature = "json_schema", derive(JsonSchema))]
     28 pub struct ClaimGeneratorInfo {
     29     /// A human readable string naming the claim_generator
     30     pub name: String,
     31     /// A human readable string of the product's version
     32     #[serde(skip_serializing_if = "Option::is_none")]
     33     pub version: Option<String>,
     34     /// hashed URI to the icon (either embedded or remote)
     35     #[serde(skip_serializing_if = "Option::is_none")]
     36     pub icon: Option<UriOrResource>,
     37     // Any other values that are not part of the standard
     38     #[serde(flatten)]
     39     other: HashMap<String, Value>,
     40 }
     41 
     42 impl Default for ClaimGeneratorInfo {
     43     fn default() -> Self {
     44         Self {
     45             name: crate::NAME.to_string(),
     46             version: Some(env!("CARGO_PKG_VERSION").to_string()),
     47             icon: None,
     48             other: HashMap::new(),
     49         }
     50     }
     51 }
     52 
     53 impl ClaimGeneratorInfo {
     54     pub fn new<S: Into<String>>(name: S) -> Self {
     55         Self {
     56             name: name.into(),
     57             version: None,
     58             icon: None,
     59             other: HashMap::new(),
     60         }
     61     }
     62 
     63     /// Returns the software agent that performed the action.
     64     pub const fn icon(&self) -> Option<&UriOrResource> {
     65         self.icon.as_ref()
     66     }
     67 
     68     /// Sets the version of the generator.
     69     pub fn set_version<S: Into<String>>(&mut self, version: S) -> &mut Self {
     70         self.version = Some(version.into());
     71         self
     72     }
     73 
     74     /// Sets the icon of the generator.
     75     pub fn set_icon<S: Into<UriOrResource>>(&mut self, uri_or_resource: S) -> &mut Self {
     76         self.icon = Some(uri_or_resource.into());
     77         self
     78     }
     79 
     80     /// Adds a new key/value pair to the generator info.
     81     pub fn insert<K, V>(&mut self, key: K, value: V) -> &Self
     82     where
     83         K: Into<String>,
     84         V: Into<Value>,
     85     {
     86         self.other.insert(key.into(), value.into());
     87         self
     88     }
     89 
     90     /// Gets additional values by key.
     91     pub fn get(&self, key: &str) -> Option<&Value> {
     92         self.other.get(key)
     93     }
     94 }
     95 
     96 #[cfg(test)]
     97 pub mod tests {
     98     #![allow(clippy::expect_used)]
     99     #![allow(clippy::unwrap_used)]
    100 
    101     use super::*;
    102     use crate::{hashed_uri::HashedUri, resource_store::ResourceRef};
    103 
    104     #[test]
    105     fn test_resource_ref() {
    106         let mut g = super::ClaimGeneratorInfo::new("test");
    107         g.set_version("1.0")
    108             .set_icon(ResourceRef::new("image/svg", "myicon"));
    109 
    110         let json = serde_json::to_string_pretty(&g).expect("Failed to serialize");
    111         println!("{json}");
    112 
    113         let result: ClaimGeneratorInfo =
    114             serde_json::from_str(&json).expect("Failed to deserialize");
    115 
    116         assert_eq!(g, result);
    117     }
    118 
    119     #[test]
    120     fn test_hashed_uri() {
    121         let mut g = super::ClaimGeneratorInfo::new("test");
    122         g.set_version("1.0").set_icon(HashedUri::new(
    123             "self#jumbf=c2pa.databoxes.data_box".to_string(),
    124             None,
    125             b"hashed",
    126         ));
    127 
    128         let json = serde_json::to_string_pretty(&g).expect("Failed to serialize");
    129         println!("{json}");
    130 
    131         let result: ClaimGeneratorInfo =
    132             serde_json::from_str(&json).expect("Failed to deserialize");
    133 
    134         assert_eq!(g, result);
    135     }
    136 }