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 }