1use crate::lib::std::fmt;
2use crate::lib::std::str::FromStr;
3use crate::lib::std::vec::Vec;
4
5use crate::diddoc_parser;
6
7use json::JsonValue;
8
9#[derive(Clone, Debug, PartialEq)]
10pub enum PublicKeyType {
11 Rsa,
12 Ed25519,
13 EcdsaSecp256k1,
14}
15
16impl FromStr for PublicKeyType {
17 type Err = ParsePublicKeyTypeError;
18
19 fn from_str(s: &str) -> Result<Self, Self::Err> {
20 match s {
21 "RsaVerificationKey2018" => Ok(Self::Rsa),
22 "Ed25519VerificationKey2018" => Ok(Self::Ed25519),
23 "Secp256k1VerificationKey2018" => Ok(Self::EcdsaSecp256k1),
24 _ => Result::Err(ParsePublicKeyTypeError(())),
25 }
26 }
27}
28
29#[derive(Debug, Clone, PartialEq, Eq)]
30pub struct ParsePublicKeyTypeError(());
31
32impl fmt::Display for ParsePublicKeyTypeError {
33 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
34 fmt.write_str("invalid DID public key type")
35 }
36}
37
38#[derive(Clone, Debug, PartialEq)]
39pub enum PublicKeyEncoded<'a> {
40 None,
41 Pem(&'a str),
42 Jwk(&'a str),
43 Hex(&'a str),
44 Base64(&'a str),
45 Base58(&'a str),
46 Multibase(&'a str),
47 EthrAddress(&'a str),
48 Unsupported,
49}
50
51const KEYPEM_PROP: &str = "publicKeyPem";
52const KEYJWK_PROP: &str = "publicKeyJwk";
53const KEYHEX_PROP: &str = "publicKeyHex";
54const KEYB58_PROP: &str = "publicKeyBase58";
55const KEYB64_PROP: &str = "publicKeyBase64";
56const KEYMUL_PROP: &str = "publicKeyMultibase";
57const KEYETH_PROP: &str = "ethereumAddress";
58pub const KEY_FORMATS: [&str; 7] = [
59 KEYPEM_PROP,
60 KEYJWK_PROP,
61 KEYHEX_PROP,
62 KEYB58_PROP,
63 KEYB64_PROP,
64 KEYMUL_PROP,
65 KEYETH_PROP,
66];
67
68impl<'a> From<(&'a str, &'a str)> for PublicKeyEncoded<'a> {
69 fn from(s: (&'a str, &'a str)) -> Self {
70 match s.0 {
71 KEYPEM_PROP => PublicKeyEncoded::Pem(s.1),
72 KEYJWK_PROP => PublicKeyEncoded::Jwk(s.1),
73 KEYHEX_PROP => PublicKeyEncoded::Hex(s.1),
74 KEYB58_PROP => PublicKeyEncoded::Base58(s.1),
75 KEYB64_PROP => PublicKeyEncoded::Base64(s.1),
76 KEYMUL_PROP => PublicKeyEncoded::Multibase(s.1),
77 KEYETH_PROP => PublicKeyEncoded::EthrAddress(s.1),
78 _ => PublicKeyEncoded::Unsupported,
79 }
80 }
81}
82
83#[derive(Clone, Debug, PartialEq)]
84pub struct PublicKey<'a> {
85 id: &'a str,
86 key_type: PublicKeyType,
87 controller: &'a str,
88 encoded_key: PublicKeyEncoded<'a>,
89}
90
91impl<'a> PublicKey<'a> {
92 pub fn id(&self) -> &'a str {
93 self.id
94 }
95
96 pub fn key_type(&self) -> &PublicKeyType {
97 &self.key_type
98 }
99
100 pub fn controller(&self) -> &'a str {
101 self.controller
102 }
103
104 pub fn encoded_key(&self) -> &PublicKeyEncoded {
105 &self.encoded_key
106 }
107}
108
109#[derive(Debug, PartialEq)]
110pub struct PublicKeyBuilder<'a> {
111 id: &'a str,
112 key_type: PublicKeyType,
113 controller: &'a str,
114 encoded_key: PublicKeyEncoded<'a>,
115}
116
117impl<'a> PublicKeyBuilder<'a> {
118 pub fn new(id: &'a str, key_type: PublicKeyType, controller: &'a str) -> Self {
119 PublicKeyBuilder {
120 id,
121 key_type,
122 controller,
123 encoded_key: PublicKeyEncoded::None,
124 }
125 }
126
127 pub fn with_encoded_key(mut self, encoded_key: PublicKeyEncoded<'a>) -> Self {
128 self.encoded_key = encoded_key;
129 self
130 }
131
132 pub fn build(self) -> PublicKey<'a> {
133 PublicKey {
134 id: self.id,
135 key_type: self.key_type,
136 controller: self.controller,
137 encoded_key: self.encoded_key,
138 }
139 }
140}
141
142#[derive(Clone, Debug, PartialEq)]
143pub enum VerificationMethod<'a> {
144 Reference(&'a str),
145 Embedded(PublicKey<'a>),
146}
147
148#[derive(Clone, Debug, PartialEq)]
149pub enum ServiceEndpoint<'a> {
150 Uri(&'a str),
151 Object(&'a str),
152}
153
154#[derive(Clone, Debug, PartialEq)]
155pub struct Service<'a> {
156 id: &'a str,
157 svc_type: &'a str,
158 endpoint: ServiceEndpoint<'a>,
159}
160
161impl<'a> Service<'a> {
162 pub fn new(id: &'a str, svc_type: &'a str, endpoint: ServiceEndpoint<'a>) -> Self {
163 Service {
164 id,
165 svc_type,
166 endpoint,
167 }
168 }
169
170 pub fn id(&self) -> &'a str {
171 self.id
172 }
173
174 pub fn svc_type(&self) -> &'a str {
175 self.svc_type
176 }
177
178 pub fn endpoint(&self) -> &ServiceEndpoint {
179 &self.endpoint
180 }
181}
182
183#[derive(Debug, Default, PartialEq)]
184pub struct DidDocument<'a> {
185 context: &'a str,
186 id: &'a str,
187 created: Option<&'a str>,
188 updated: Option<&'a str>,
189 authentication: Vec<VerificationMethod<'a>>,
190 pub_keys: Vec<PublicKey<'a>>,
191 service: Vec<Service<'a>>,
192}
193
194impl<'a> DidDocument<'a> {
195 pub fn context(&self) -> &'a str {
196 self.context
197 }
198
199 pub fn id(&self) -> &'a str {
200 self.id
201 }
202
203 pub fn created(&self) -> Option<&'a str> {
204 self.created
205 }
206
207 pub fn updated(&self) -> Option<&'a str> {
208 self.updated
209 }
210
211 pub fn authentication(&self) -> &[VerificationMethod<'a>] {
212 &self.authentication[..]
213 }
214
215 pub fn pub_keys(&self) -> &[PublicKey<'a>] {
216 &self.pub_keys[..]
217 }
218
219 pub fn service(&self) -> &[Service<'a>] {
220 &self.service[..]
221 }
222
223 pub fn parse(json: &'a JsonValue) -> Result<Self, &'a str> {
224 diddoc_parser::parse_did_doc(json)
225 }
226}
227
228#[derive(Debug, Default, PartialEq)]
229pub struct DidDocumentBuilder<'a> {
230 context: &'a str,
231 id: &'a str,
232 created: Option<&'a str>,
233 updated: Option<&'a str>,
234 authentication: Vec<VerificationMethod<'a>>,
235 pub_keys: Vec<PublicKey<'a>>,
236 service: Vec<Service<'a>>,
237}
238
239impl<'a> DidDocumentBuilder<'a> {
240 pub fn new(id: &'a str) -> Self {
241 DidDocumentBuilder {
242 context: diddoc_parser::GENERIC_DID_CTX,
243 id,
244 ..Default::default()
245 }
246 }
247
248 pub fn created_on(mut self, created: &'a str) -> Self {
249 self.created = Some(created);
250 self
251 }
252
253 pub fn updated_on(mut self, updated: &'a str) -> Self {
254 self.updated = Some(updated);
255 self
256 }
257
258 pub fn with_authentication(mut self, authentication: Vec<VerificationMethod<'a>>) -> Self {
259 self.authentication = authentication;
260 self
261 }
262
263 pub fn with_pubkeys(mut self, pub_keys: Vec<PublicKey<'a>>) -> Self {
264 self.pub_keys = pub_keys;
265 self
266 }
267
268 pub fn with_services(mut self, services: Vec<Service<'a>>) -> Self {
269 self.service = services;
270 self
271 }
272
273 pub fn build(self) -> DidDocument<'a> {
274 DidDocument {
275 context: self.context,
276 id: self.id,
277 created: self.created,
278 updated: self.updated,
279 authentication: self.authentication,
280 pub_keys: self.pub_keys,
281 service: self.service,
282 }
283 }
284}
285
286#[cfg(test)]
287mod tests {
288 use super::diddoc_parser::GENERIC_DID_CTX;
289 use super::FromStr;
290 use super::{
291 DidDocument, DidDocumentBuilder, ParsePublicKeyTypeError, PublicKey, PublicKeyBuilder,
292 PublicKeyEncoded, PublicKeyType, Service, ServiceEndpoint, VerificationMethod,
293 };
294
295 const TEST_ENCODED_KEY: &str = "0x1234567890";
296
297 #[test]
298 fn public_key_type_fromstr_trait_for_rsa() {
299 assert_eq!(
300 PublicKeyType::from_str("RsaVerificationKey2018"),
301 Ok(PublicKeyType::Rsa)
302 );
303 }
304
305 #[test]
306 fn public_key_type_fromstr_trait_for_ed25519() {
307 assert_eq!(
308 PublicKeyType::from_str("Ed25519VerificationKey2018"),
309 Ok(PublicKeyType::Ed25519)
310 );
311 }
312
313 #[test]
314 fn public_key_type_fromstr_trait_for_ecdsasecp256k1() {
315 assert_eq!(
316 PublicKeyType::from_str("Secp256k1VerificationKey2018"),
317 Ok(PublicKeyType::EcdsaSecp256k1)
318 );
319 }
320
321 #[test]
322 fn public_key_type_fromstr_trait_for_invalid_case() {
323 assert_eq!(
324 PublicKeyType::from_str("rsaverificationkey2018"),
325 Err(ParsePublicKeyTypeError(()))
326 );
327 assert_eq!(
328 PublicKeyType::from_str("ed25519verificationkey2018"),
329 Err(ParsePublicKeyTypeError(()))
330 );
331 assert_eq!(
332 PublicKeyType::from_str("secp256k1verificationkey2018"),
333 Err(ParsePublicKeyTypeError(()))
334 );
335 }
336
337 #[test]
338 fn public_key_type_fromstr_trait_for_unsupported() {
339 assert_eq!(
340 PublicKeyType::from_str("azertyuiop"),
341 Err(ParsePublicKeyTypeError(()))
342 );
343 }
344
345 #[test]
346 fn public_key_type_error_display_trait() {
347 assert_eq!(
348 format!("{}", ParsePublicKeyTypeError(())),
349 "invalid DID public key type"
350 );
351 }
352
353 #[test]
354 fn public_key_encoded_from_trait_for_pem() {
355 assert_eq!(
356 PublicKeyEncoded::from((super::KEYPEM_PROP, TEST_ENCODED_KEY)),
357 PublicKeyEncoded::Pem(TEST_ENCODED_KEY)
358 )
359 }
360
361 #[test]
362 fn public_key_encoded_from_trait_for_jwk() {
363 assert_eq!(
364 PublicKeyEncoded::from((super::KEYJWK_PROP, TEST_ENCODED_KEY)),
365 PublicKeyEncoded::Jwk(TEST_ENCODED_KEY)
366 )
367 }
368
369 #[test]
370 fn public_key_encoded_from_trait_for_hex() {
371 assert_eq!(
372 PublicKeyEncoded::from((super::KEYHEX_PROP, TEST_ENCODED_KEY)),
373 PublicKeyEncoded::Hex(TEST_ENCODED_KEY)
374 )
375 }
376
377 #[test]
378 fn public_key_encoded_from_trait_for_base64() {
379 assert_eq!(
380 PublicKeyEncoded::from((super::KEYB64_PROP, TEST_ENCODED_KEY)),
381 PublicKeyEncoded::Base64(TEST_ENCODED_KEY)
382 )
383 }
384
385 #[test]
386 fn public_key_encoded_from_trait_for_base58() {
387 assert_eq!(
388 PublicKeyEncoded::from((super::KEYB58_PROP, TEST_ENCODED_KEY)),
389 PublicKeyEncoded::Base58(TEST_ENCODED_KEY)
390 )
391 }
392
393 #[test]
394 fn public_key_encoded_from_trait_for_multibase() {
395 assert_eq!(
396 PublicKeyEncoded::from((super::KEYMUL_PROP, TEST_ENCODED_KEY)),
397 PublicKeyEncoded::Multibase(TEST_ENCODED_KEY)
398 )
399 }
400
401 #[test]
402 fn public_key_encoded_from_trait_for_ethraddress() {
403 assert_eq!(
404 PublicKeyEncoded::from((super::KEYETH_PROP, TEST_ENCODED_KEY)),
405 PublicKeyEncoded::EthrAddress(TEST_ENCODED_KEY)
406 )
407 }
408
409 #[test]
410 fn public_key_encoded_from_trait_for_unsupported() {
411 assert_eq!(
412 PublicKeyEncoded::from(("azertyuiop", TEST_ENCODED_KEY)),
413 PublicKeyEncoded::Unsupported
414 )
415 }
416
417 #[test]
418 fn public_key_property_accessors() {
419 let pubkey = PublicKey {
420 id: "did:example:123456789abcdefghi#keys-1",
421 key_type: PublicKeyType::Ed25519,
422 controller: "did:example:123456789abcdefghi",
423 encoded_key: PublicKeyEncoded::Base58("H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"),
424 };
425 assert_eq!(pubkey.id(), "did:example:123456789abcdefghi#keys-1");
426 assert_eq!(pubkey.key_type(), &PublicKeyType::Ed25519);
427 assert_eq!(pubkey.controller(), "did:example:123456789abcdefghi");
428 assert_eq!(
429 pubkey.encoded_key(),
430 &PublicKeyEncoded::Base58("H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV")
431 );
432 }
433
434 #[test]
435 fn public_key_builder_for_rsa_key() {
436 assert_eq!(
437 PublicKeyBuilder::new(
438 "did:example:123456789abcdefghi#keys-1",
439 PublicKeyType::Rsa,
440 "did:example:123456789abcdefghi"
441 )
442 .with_encoded_key(PublicKeyEncoded::Pem(
443 "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
444 ))
445 .build(),
446 PublicKey {
447 id: "did:example:123456789abcdefghi#keys-1",
448 key_type: PublicKeyType::Rsa,
449 controller: "did:example:123456789abcdefghi",
450 encoded_key: PublicKeyEncoded::Pem(
451 "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
452 ),
453 }
454 )
455 }
456
457 #[test]
458 fn public_key_builder_for_ed25519_key() {
459 assert_eq!(
460 PublicKeyBuilder::new(
461 "did:example:123456789abcdefghi#keys-2",
462 PublicKeyType::Ed25519,
463 "did:example:pqrstuvwxyz0987654321"
464 )
465 .with_encoded_key(PublicKeyEncoded::Base58(
466 "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
467 ))
468 .build(),
469 PublicKey {
470 id: "did:example:123456789abcdefghi#keys-2",
471 key_type: PublicKeyType::Ed25519,
472 controller: "did:example:pqrstuvwxyz0987654321",
473 encoded_key: PublicKeyEncoded::Base58(
474 "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
475 ),
476 }
477 )
478 }
479
480 #[test]
481 fn public_key_builder_for_edcsasecp256k1_key() {
482 assert_eq!(
483 PublicKeyBuilder::new(
484 "did:example:123456789abcdefghi#keys-3",
485 PublicKeyType::EcdsaSecp256k1,
486 "did:example:123456789abcdefghi"
487 )
488 .with_encoded_key(PublicKeyEncoded::Hex(
489 "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71"
490 ))
491 .build(),
492 PublicKey {
493 id: "did:example:123456789abcdefghi#keys-3",
494 key_type: PublicKeyType::EcdsaSecp256k1,
495 controller: "did:example:123456789abcdefghi",
496 encoded_key: PublicKeyEncoded::Hex(
497 "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71"
498 ),
499 }
500 )
501 }
502
503 #[test]
504 fn service_property_accessors() {
505 let svc = Service::new(
506 "did:example:123456789abcdefghi#openid",
507 "OpenIdConnectVersion1.0Service",
508 ServiceEndpoint::Uri("https://openid.example.com/"),
509 );
510 assert_eq!(svc.id(), "did:example:123456789abcdefghi#openid");
511 assert_eq!(svc.svc_type(), "OpenIdConnectVersion1.0Service");
512 assert_eq!(
513 svc.endpoint(),
514 &ServiceEndpoint::Uri("https://openid.example.com/")
515 );
516 }
517
518 #[test]
519 fn did_document_property_accessors() {
520 let pubkey = PublicKey {
521 id: "did:example:123456789abcdefghi#keys-1",
522 key_type: PublicKeyType::Ed25519,
523 controller: "did:example:123456789abcdefghi",
524 encoded_key: PublicKeyEncoded::Base58("H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"),
525 };
526
527 let verif_method = VerificationMethod::Embedded(pubkey.clone());
528
529 let service = Service {
530 id: "did:example:123456789abcdefghi#openid",
531 svc_type: "OpenIdConnectVersion1.0Service",
532 endpoint: ServiceEndpoint::Uri("https://openid.example.com/"),
533 };
534
535 let did_doc = DidDocument {
536 context: "https://www.w3.org/2019/did/v1",
537 id: "did:example:123456789abcdefghi",
538 created: Some("2002-10-10T17:00:00Z"),
539 updated: Some("2002-10-10T17:00:00Z"),
540 authentication: vec![verif_method.clone()],
541 pub_keys: vec![pubkey.clone()],
542 service: vec![service.clone()],
543 };
544 assert_eq!(did_doc.context(), "https://www.w3.org/2019/did/v1");
545 assert_eq!(did_doc.id(), "did:example:123456789abcdefghi");
546 assert_eq!(did_doc.created(), Some("2002-10-10T17:00:00Z"));
547 assert_eq!(did_doc.created(), Some("2002-10-10T17:00:00Z"));
548 assert_eq!(did_doc.authentication(), &[verif_method]);
549 assert_eq!(did_doc.pub_keys(), &[pubkey]);
550 assert_eq!(did_doc.service(), &[service]);
551 }
552
553 #[test]
554 fn did_document_builder_with_pub_keys() {
555 assert_eq!(
556 DidDocumentBuilder::new("did:example:123456789abcdefghi")
557 .with_pubkeys(vec![
558 PublicKeyBuilder::new(
559 "did:example:123456789abcdefghi#keys-1",
560 PublicKeyType::Rsa,
561 "did:example:123456789abcdefghi"
562 )
563 .with_encoded_key(PublicKeyEncoded::Pem(
564 "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
565 ))
566 .build(),
567 PublicKeyBuilder::new(
568 "did:example:123456789abcdefghi#keys-2",
569 PublicKeyType::Ed25519,
570 "did:example:pqrstuvwxyz0987654321"
571 )
572 .with_encoded_key(PublicKeyEncoded::Base58(
573 "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
574 ))
575 .build(),
576 PublicKeyBuilder::new(
577 "did:example:123456789abcdefghi#keys-3",
578 PublicKeyType::EcdsaSecp256k1,
579 "did:example:123456789abcdefghi"
580 )
581 .with_encoded_key(PublicKeyEncoded::Hex(
582 "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71"
583 ))
584 .build()
585 ])
586 .build(),
587 DidDocument {
588 context: GENERIC_DID_CTX,
589 id: "did:example:123456789abcdefghi",
590 pub_keys: vec![
591 PublicKey {
592 id: "did:example:123456789abcdefghi#keys-1",
593 key_type: PublicKeyType::Rsa,
594 controller: "did:example:123456789abcdefghi",
595 encoded_key: PublicKeyEncoded::Pem(
596 "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
597 ),
598 },
599 PublicKey {
600 id: "did:example:123456789abcdefghi#keys-2",
601 key_type: PublicKeyType::Ed25519,
602 controller: "did:example:pqrstuvwxyz0987654321",
603 encoded_key: PublicKeyEncoded::Base58(
604 "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
605 ),
606 },
607 PublicKey {
608 id: "did:example:123456789abcdefghi#keys-3",
609 key_type: PublicKeyType::EcdsaSecp256k1,
610 controller: "did:example:123456789abcdefghi",
611 encoded_key: PublicKeyEncoded::Hex(
612 "02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71"
613 ),
614 }
615 ],
616 ..Default::default()
617 }
618 )
619 }
620
621 #[test]
622 fn did_document_builder_with_auth_reference_verif_method() {
623 assert_eq!(
624 DidDocumentBuilder::new("did:example:123456789abcdefghi")
625 .with_authentication(vec![VerificationMethod::Reference(
626 "did:example:123456789abcdefghi#keys-1"
627 )])
628 .with_pubkeys(vec![PublicKeyBuilder::new(
629 "did:example:123456789abcdefghi#keys-1",
630 PublicKeyType::Rsa,
631 "did:example:123456789abcdefghi"
632 )
633 .with_encoded_key(PublicKeyEncoded::Pem(
634 "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
635 ))
636 .build()])
637 .build(),
638 DidDocument {
639 context: GENERIC_DID_CTX,
640 id: "did:example:123456789abcdefghi",
641 authentication: vec![VerificationMethod::Reference(
642 "did:example:123456789abcdefghi#keys-1"
643 )],
644 pub_keys: vec![PublicKey {
645 id: "did:example:123456789abcdefghi#keys-1",
646 key_type: PublicKeyType::Rsa,
647 controller: "did:example:123456789abcdefghi",
648 encoded_key: PublicKeyEncoded::Pem(
649 "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
650 ),
651 }],
652 ..Default::default()
653 }
654 )
655 }
656
657 #[test]
658 fn did_document_builder_with_auth_embedded_verif_method() {
659 assert_eq!(
660 DidDocumentBuilder::new("did:example:123456789abcdefghi")
661 .with_authentication(vec![VerificationMethod::Embedded(
662 PublicKeyBuilder::new(
663 "did:example:123456789abcdefghi#keys-2",
664 PublicKeyType::Ed25519,
665 "did:example:123456789abcdefghi"
666 )
667 .with_encoded_key(PublicKeyEncoded::Base58(
668 "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
669 ))
670 .build(),
671 )])
672 .build(),
673 DidDocument {
674 context: GENERIC_DID_CTX,
675 id: "did:example:123456789abcdefghi",
676 authentication: vec![VerificationMethod::Embedded(PublicKey {
677 id: "did:example:123456789abcdefghi#keys-2",
678 key_type: PublicKeyType::Ed25519,
679 controller: "did:example:123456789abcdefghi",
680 encoded_key: PublicKeyEncoded::Base58(
681 "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
682 ),
683 })],
684 ..Default::default()
685 }
686 )
687 }
688
689 #[test]
690 fn did_document_builder_with_service_uri_endpoint() {
691 assert_eq!(
692 DidDocumentBuilder::new("did:example:123456789abcdefghi")
693 .with_services(vec![Service::new(
694 "did:example:123456789abcdefghi#openid",
695 "OpenIdConnectVersion1.0Service",
696 ServiceEndpoint::Uri("https://openid.example.com/")
697 )])
698 .build(),
699 DidDocument {
700 context: GENERIC_DID_CTX,
701 id: "did:example:123456789abcdefghi",
702 service: vec![Service {
703 id: "did:example:123456789abcdefghi#openid",
704 svc_type: "OpenIdConnectVersion1.0Service",
705 endpoint: ServiceEndpoint::Uri("https://openid.example.com/")
706 }],
707 ..Default::default()
708 }
709 )
710 }
711
712 #[test]
713 fn did_document_builder_with_created() {
714 assert_eq!(
715 DidDocumentBuilder::new("did:example:123456789abcdefghi")
716 .created_on("2002-10-10T17:00:00Z")
717 .build(),
718 DidDocument {
719 context: GENERIC_DID_CTX,
720 id: "did:example:123456789abcdefghi",
721 created: Some("2002-10-10T17:00:00Z"),
722 ..Default::default()
723 }
724 )
725 }
726
727 #[test]
728 fn did_document_builder_with_updated() {
729 assert_eq!(
730 DidDocumentBuilder::new("did:example:123456789abcdefghi")
731 .updated_on("2002-10-10T17:00:00Z")
732 .build(),
733 DidDocument {
734 context: GENERIC_DID_CTX,
735 id: "did:example:123456789abcdefghi",
736 updated: Some("2002-10-10T17:00:00Z"),
737 ..Default::default()
738 }
739 )
740 }
741}