prople_did_core/verifiable/
vp.rs1use rst_common::standard::serde::{self, Deserialize, Serialize};
2use rst_common::standard::serde_json;
3
4use crate::types::{DIDError, JSONValue, ToJCS, ToJSON, Validator};
5use crate::verifiable::objects::VC;
6use crate::verifiable::types::{Context, Type};
7
8use crate::verifiable::proof::types::{ProofError, Proofable};
9use crate::verifiable::proof::Proof;
10
11#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
16#[serde(crate = "self::serde")]
17pub struct VP {
18 #[serde(rename = "@context")]
19 pub contexts: Vec<Context>,
20
21 #[serde(rename = "type")]
22 pub types: Vec<Type>,
23
24 #[serde(rename = "verifiableCredential")]
25 pub verifiable_credential: Vec<VC>,
26
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub proof: Option<Proof>,
29
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub holder: Option<String>,
32}
33
34impl Default for VP {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39
40impl VP {
41 pub fn new() -> Self {
42 Self {
43 contexts: Vec::new(),
44 types: Vec::new(),
45 verifiable_credential: Vec::new(),
46 proof: None,
47 holder: None,
48 }
49 }
50
51 pub fn add_context(&mut self, context: Context) -> &mut Self {
52 self.contexts.push(context);
53 self
54 }
55
56 pub fn add_type(&mut self, t: Type) -> &mut Self {
57 self.types.push(t);
58 self
59 }
60
61 pub fn add_credential(&mut self, cred: VC) -> &mut Self {
62 self.verifiable_credential.push(cred);
63 self
64 }
65
66 pub fn add_proof(&mut self, proof: Proof) -> &mut Self {
67 self.proof = Some(proof);
68 self
69 }
70
71 pub fn set_holder(&mut self, holder: String) -> &mut Self {
72 self.holder = Some(holder);
73 self
74 }
75}
76
77impl ToJSON for VP {
78 fn to_json(&self) -> Result<JSONValue, DIDError> {
79 match self.validate() {
80 Ok(_) => {
81 let jsonstr = serde_json::to_string(self)
82 .map_err(|err| DIDError::GenerateJSONError(err.to_string()))?;
83
84 Ok(JSONValue::from(jsonstr))
85 }
86 Err(err) => Err(err),
87 }
88 }
89}
90
91impl ToJCS for VP {
92 fn to_jcs(&self) -> Result<String, DIDError> {
93 match self.validate() {
94 Ok(_) => serde_jcs::to_string(self)
95 .map_err(|err| DIDError::GenerateJSONError(err.to_string())),
96 Err(err) => Err(err),
97 }
98 }
99}
100
101impl Validator for VP {
102 fn validate(&self) -> Result<(), DIDError> {
103 if self.contexts.is_empty() {
104 return Err(DIDError::GenerateJSONError(String::from(
105 "vp: empty context",
106 )));
107 }
108
109 if self.types.is_empty() {
110 return Err(DIDError::GenerateJSONError(String::from("vp: empty types")));
111 }
112
113 if self.verifiable_credential.is_empty() {
114 return Err(DIDError::GenerateJSONError(String::from(
115 "vp: empty credentials",
116 )));
117 }
118
119 Ok(())
120 }
121}
122
123impl Proofable for VP {
124 fn get_proof(&self) -> Option<Proof> {
125 self.proof.to_owned()
126 }
127
128 fn setup_proof(&mut self, proof: Proof) -> &mut Self {
129 self.add_proof(proof);
130 self
131 }
132
133 fn parse_json_bytes(bytes: Vec<u8>) -> Result<Self, ProofError> {
134 let parsed: Self = serde_json::from_slice(bytes.as_slice())
135 .map_err(|err| ProofError::ProofGenerationError(err.to_string()))?;
136
137 Ok(parsed)
138 }
139
140 fn remove_proof(&self) -> Self {
141 let mut vp = self.clone();
142 vp.proof = None;
143 vp
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 use super::*;
150
151 #[test]
152 fn test_generate_json() {
153 let vc = VC::new("id1".to_string(), "issuer".to_string());
154 let mut vp = VP::new();
155
156 vp.add_context("context1".to_string())
157 .add_context("context2".to_string())
158 .add_type("type".to_string())
159 .add_credential(vc);
160
161 let try_json = vp.to_json();
162 assert!(!try_json.is_err());
163
164 let expected_json = r#"{"@context":["context1","context2"],"type":["type"],"verifiableCredential":[{"@context":[],"type":[],"credentialSubject":null,"id":"id1","issuer":"issuer"}]}"#;
165 assert_eq!(JSONValue::from(expected_json), try_json.unwrap())
166 }
167
168 #[test]
169 fn test_generate_jcs() {
170 let vc = VC::new("id1".to_string(), "issuer".to_string());
171 let mut vp = VP::new();
172
173 vp.add_context("context1".to_string())
174 .add_context("context2".to_string())
175 .add_type("type".to_string())
176 .add_credential(vc);
177
178 let try_json = vp.to_jcs();
179 assert!(!try_json.is_err());
180 }
181
182 #[test]
183 fn test_validate_failed_context_empty() {
184 let vp = VP::new();
185 let try_json = vp.to_json();
186 assert!(try_json.is_err());
187 assert_eq!(
188 DIDError::GenerateJSONError("vp: empty context".to_string()),
189 try_json.unwrap_err()
190 )
191 }
192
193 #[test]
194 fn test_validate_failed_types_empty() {
195 let mut vp = VP::new();
196 vp.add_context("context1".to_string());
197
198 let try_json = vp.to_json();
199 assert!(try_json.is_err());
200 assert_eq!(
201 DIDError::GenerateJSONError("vp: empty types".to_string()),
202 try_json.unwrap_err()
203 )
204 }
205
206 #[test]
207 fn test_validate_failed_credential_empty() {
208 let mut vp = VP::new();
209 vp.add_context("context1".to_string());
210 vp.add_type("type".to_string());
211
212 let try_json = vp.to_json();
213 assert!(try_json.is_err());
214 assert_eq!(
215 DIDError::GenerateJSONError("vp: empty credentials".to_string()),
216 try_json.unwrap_err()
217 )
218 }
219}