1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9use crate::message::agent::TapParticipant;
10use crate::utils::NameHashable;
11
12#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
17pub struct Party {
18 #[serde(rename = "@id")]
20 pub id: String,
21
22 #[serde(flatten)]
26 pub metadata: HashMap<String, serde_json::Value>,
27}
28
29impl TapParticipant for Party {
30 fn id(&self) -> &str {
31 &self.id
32 }
33}
34
35impl Party {
36 pub fn new(id: &str) -> Self {
38 Self {
39 id: id.to_string(),
40 metadata: HashMap::new(),
41 }
42 }
43
44 pub fn with_metadata(id: &str, metadata: HashMap<String, serde_json::Value>) -> Self {
46 Self {
47 id: id.to_string(),
48 metadata,
49 }
50 }
51
52 pub fn add_metadata(&mut self, key: String, value: serde_json::Value) {
54 self.metadata.insert(key, value);
55 }
56
57 pub fn with_country(mut self, country_code: &str) -> Self {
59 self.metadata.insert(
60 "https://schema.org/addressCountry".to_string(),
61 serde_json::Value::String(country_code.to_string()),
62 );
63 self
64 }
65
66 pub fn with_lei(mut self, lei_code: &str) -> Self {
68 self.metadata.insert(
69 "https://schema.org/leiCode".to_string(),
70 serde_json::Value::String(lei_code.to_string()),
71 );
72 self
73 }
74
75 pub fn with_mcc(mut self, mcc: &str) -> Self {
77 self.metadata.insert(
78 "mcc".to_string(),
79 serde_json::Value::String(mcc.to_string()),
80 );
81 self
82 }
83
84 pub fn get_metadata(&self, key: &str) -> Option<&serde_json::Value> {
86 self.metadata.get(key)
87 }
88
89 pub fn country(&self) -> Option<String> {
91 self.get_metadata("https://schema.org/addressCountry")
92 .and_then(|v| v.as_str())
93 .map(|s| s.to_string())
94 }
95
96 pub fn lei_code(&self) -> Option<String> {
98 self.get_metadata("https://schema.org/leiCode")
99 .and_then(|v| v.as_str())
100 .map(|s| s.to_string())
101 }
102
103 pub fn mcc(&self) -> Option<String> {
105 self.get_metadata("mcc")
106 .and_then(|v| v.as_str())
107 .map(|s| s.to_string())
108 }
109
110 pub fn with_name_hash(mut self, name: &str) -> Self {
112 let hash = Self::hash_name(name);
113 self.metadata
114 .insert("nameHash".to_string(), serde_json::Value::String(hash));
115 self
116 }
117
118 pub fn name_hash(&self) -> Option<String> {
120 self.get_metadata("nameHash")
121 .and_then(|v| v.as_str())
122 .map(|s| s.to_string())
123 }
124
125 pub fn set_name_hash(&mut self, hash: String) {
127 self.metadata
128 .insert("nameHash".to_string(), serde_json::Value::String(hash));
129 }
130}
131
132impl NameHashable for Party {}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138 use serde_json;
139
140 #[test]
141 fn test_party_creation() {
142 let party = Party::new("did:example:alice");
143 assert_eq!(party.id, "did:example:alice");
144 assert!(party.metadata.is_empty());
145 }
146
147 #[test]
148 fn test_party_with_metadata() {
149 let mut metadata = HashMap::new();
150 metadata.insert(
151 "name".to_string(),
152 serde_json::Value::String("Alice".to_string()),
153 );
154
155 let party = Party::with_metadata("did:example:alice", metadata);
156 assert_eq!(party.id, "did:example:alice");
157 assert_eq!(
158 party.get_metadata("name").unwrap().as_str().unwrap(),
159 "Alice"
160 );
161 }
162
163 #[test]
164 fn test_party_with_country() {
165 let party = Party::new("did:example:alice").with_country("de");
166 assert_eq!(party.country().unwrap(), "de");
167 }
168
169 #[test]
170 fn test_party_with_lei() {
171 let party = Party::new("did:web:example.com").with_lei("LEI123456789");
172 assert_eq!(party.lei_code().unwrap(), "LEI123456789");
173 }
174
175 #[test]
176 fn test_party_with_mcc() {
177 let party = Party::new("did:web:merchant.com").with_mcc("5812");
178 assert_eq!(party.mcc().unwrap(), "5812");
179 }
180
181 #[test]
182 fn test_party_serialization() {
183 let party = Party::new("did:example:alice")
184 .with_country("de")
185 .with_lei("LEI123");
186
187 let json = serde_json::to_string(&party).unwrap();
188 let deserialized: Party = serde_json::from_str(&json).unwrap();
189
190 assert_eq!(party, deserialized);
191 assert_eq!(deserialized.country().unwrap(), "de");
192 assert_eq!(deserialized.lei_code().unwrap(), "LEI123");
193 }
194
195 #[test]
196 fn test_party_json_ld_format() {
197 let party = Party::new("did:example:alice").with_country("de");
198 let json = serde_json::to_value(&party).unwrap();
199
200 assert_eq!(json["@id"], "did:example:alice");
201 assert_eq!(json["https://schema.org/addressCountry"], "de");
202 }
203
204 #[test]
205 fn test_party_with_name_hash() {
206 let party = Party::new("did:example:alice").with_name_hash("Alice Lee");
207 assert_eq!(
208 party.name_hash().unwrap(),
209 "b117f44426c9670da91b563db728cd0bc8bafa7d1a6bb5e764d1aad2ca25032e"
210 );
211 }
212
213 #[test]
214 fn test_party_name_hash_serialization() {
215 let party = Party::new("did:example:alice")
216 .with_name_hash("Alice Lee")
217 .with_country("US");
218
219 let json = serde_json::to_value(&party).unwrap();
220 assert_eq!(json["@id"], "did:example:alice");
221 assert_eq!(
222 json["nameHash"],
223 "b117f44426c9670da91b563db728cd0bc8bafa7d1a6bb5e764d1aad2ca25032e"
224 );
225 assert_eq!(json["https://schema.org/addressCountry"], "US");
226 }
227}