Skip to main content

fi_verifiable_data/
document.rs

1use std::{
2    borrow::{Borrow, BorrowMut},
3    collections::HashMap,
4};
5
6use serde::{Deserialize, Serialize};
7use wasm_bindgen::prelude::wasm_bindgen;
8
9#[cfg(feature = "wasm")]
10use wasm_bindgen::prelude::JsValue;
11
12use crate::error::FiError;
13
14pub trait DocResolver {
15    fn resolve(&self, url: &str) -> Option<VerificationDocument>;
16}
17
18#[derive(Clone, Serialize, Deserialize)]
19#[wasm_bindgen]
20pub struct VerificationDocument {
21    private_key: Option<Vec<u8>>,
22    public_key: Option<Vec<u8>>,
23    id: String,
24}
25
26#[wasm_bindgen]
27impl VerificationDocument {
28    #[wasm_bindgen(constructor)]
29    pub fn new(
30        id: String,
31        private_key: Option<Vec<u8>>,
32        public_key: Option<Vec<u8>>,
33    ) -> VerificationDocument {
34        return VerificationDocument {
35            id,
36            private_key,
37            public_key,
38        };
39    }
40}
41
42impl VerificationDocument {
43    pub fn get_private_key(&self) -> &Option<Vec<u8>> {
44        self.private_key.borrow()
45    }
46
47    pub fn get_public_key(&self) -> &Option<Vec<u8>> {
48        self.public_key.borrow()
49    }
50
51    pub fn get_id(&self) -> &String {
52        self.id.borrow()
53    }
54
55    pub fn get_private_key_mut(&mut self) -> &mut Option<Vec<u8>> {
56        self.private_key.borrow_mut()
57    }
58
59    pub fn get_public_key_mut(&mut self) -> &mut Option<Vec<u8>> {
60        self.public_key.borrow_mut()
61    }
62
63    pub fn get_id_mut(&mut self) -> &mut String {
64        self.id.borrow_mut()
65    }
66}
67
68#[wasm_bindgen]
69pub struct DocumentLoader {
70    docs: HashMap<String, VerificationDocument>,
71    doc_resolvers: Vec<Box<dyn DocResolver>>,
72}
73
74#[cfg(not(feature = "wasm"))]
75impl DocumentLoader {
76    pub fn new(docs: Option<HashMap<String, VerificationDocument>>) -> Result<Self, FiError> {
77        return Ok(DocumentLoader {
78            doc_resolvers: Vec::new(),
79            docs: match docs {
80                Some(val) => val,
81                None => HashMap::new(),
82            },
83        });
84    }
85
86    pub fn get_verification_document(&mut self, url: &str) -> Option<VerificationDocument> {
87        get_verification_document(self, url)
88    }
89}
90
91fn get_verification_document(doc: &mut DocumentLoader, url: &str) -> Option<VerificationDocument> {
92    if doc.docs.contains_key(url) {
93        let val: VerificationDocument = match doc.docs.get_key_value(url) {
94            None => return None,
95            Some((_url, _doc)) => _doc.clone(),
96        };
97        return Some(val);
98    }
99
100    let itr = doc.doc_resolvers.iter();
101    for resolver in itr {
102        let value = resolver.resolve(url);
103        if value.is_some() {
104            let val = value.clone().unwrap();
105            doc.docs.insert(String::from(url), val);
106            return Some(value.unwrap());
107        }
108    }
109
110    return None;
111}
112
113#[wasm_bindgen]
114#[cfg(feature = "wasm")]
115impl DocumentLoader {
116    #[wasm_bindgen(constructor)]
117    pub fn new(docs: JsValue) -> Result<DocumentLoader, FiError> {
118        let mut values: Option<HashMap<String, VerificationDocument>> = None;
119
120        if docs.is_null() || docs.is_undefined() {
121            values = match serde_wasm_bindgen::from_value(docs) {
122                Ok(val) => val,
123                Err(error) => return Err(FiError::new(error.to_string().as_str())),
124            };
125        }
126
127        return Ok(DocumentLoader {
128            doc_resolvers: Vec::new(),
129            docs: match values {
130                Some(val) => val,
131                None => HashMap::new(),
132            },
133        });
134    }
135
136    #[wasm_bindgen(js_name = "getVerificationDocument")]
137    pub fn get_verification_document(&mut self, url: &str) -> Option<VerificationDocument> {
138        get_verification_document(self, url)
139    }
140}