fi-verifiable-data 0.0.1

VC and VP wrapper for rust and WASM. fi-digital-signatures crate is used to sign and verify the data objects.
Documentation
use std::{
    borrow::{Borrow, BorrowMut},
    collections::HashMap,
};

use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::wasm_bindgen;

#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::JsValue;

use crate::error::Error;

pub trait DocResolver {
    fn resolve(&self, url: &str) -> Option<VerificationDocument>;
}

#[derive(Clone, Serialize, Deserialize)]
#[wasm_bindgen]
pub struct VerificationDocument {
    private_key: Option<Vec<u8>>,
    public_key: Option<Vec<u8>>,
    id: String,
}

impl VerificationDocument {
    pub fn new(
        id: String,
        private_key: Option<Vec<u8>>,
        public_key: Option<Vec<u8>>,
    ) -> VerificationDocument {
        return VerificationDocument {
            id,
            private_key,
            public_key,
        };
    }

    pub fn get_private_key(&self) -> &Option<Vec<u8>> {
        self.private_key.borrow()
    }

    pub fn get_public_key(&self) -> &Option<Vec<u8>> {
        self.public_key.borrow()
    }

    pub fn get_id(&self) -> &String {
        self.id.borrow()
    }

    pub fn get_private_key_mut(&mut self) -> &mut Option<Vec<u8>> {
        self.private_key.borrow_mut()
    }

    pub fn get_public_key_mut(&mut self) -> &mut Option<Vec<u8>> {
        self.public_key.borrow_mut()
    }

    pub fn get_id_mut(&mut self) -> &mut String {
        self.id.borrow_mut()
    }
}

#[wasm_bindgen]
pub struct DocumentLoader {
    docs: HashMap<String, VerificationDocument>,
    doc_resolvers: Vec<Box<dyn DocResolver>>,
}

#[cfg(not(feature = "wasm"))]
impl DocumentLoader {
    pub fn new(docs: Option<HashMap<String, VerificationDocument>>) -> Result<Self, Error> {
        return Ok(DocumentLoader {
            doc_resolvers: Vec::new(),
            docs: match docs {
                Some(val) => val,
                None => HashMap::new(),
            },
        });
    }

    pub fn get_verification_document(&mut self, url: &str) -> Option<VerificationDocument> {
        get_verification_document(self, url)
    }
}

fn get_verification_document(doc: &mut DocumentLoader, url: &str) -> Option<VerificationDocument> {
    if doc.docs.contains_key(url) {
        let val: VerificationDocument = match doc.docs.get_key_value(url) {
            None => return None,
            Some((_url, _doc)) => _doc.clone(),
        };
        return Some(val);
    }

    let itr = doc.doc_resolvers.iter();
    for resolver in itr {
        let value = resolver.resolve(url);
        if value.is_some() {
            let val = value.clone().unwrap();
            doc.docs.insert(String::from(url), val);
            return Some(value.unwrap());
        }
    }

    return None;
}

#[wasm_bindgen]
#[cfg(feature = "wasm")]
impl DocumentLoader {
    #[wasm_bindgen(constructor)]
    pub fn new(docs: JsValue) -> Result<DocumentLoader, Error> {
        let mut values: Option<HashMap<String, VerificationDocument>> = None;

        if docs.is_null() || docs.is_undefined() {
            values = match serde_wasm_bindgen::from_value(docs) {
                Ok(val) => val,
                Err(error) => return Err(Error::new(error.to_string().as_str())),
            };
        }

        return Ok(DocumentLoader {
            doc_resolvers: Vec::new(),
            docs: match values {
                Some(val) => val,
                None => HashMap::new(),
            },
        });
    }

    #[wasm_bindgen(js_name = "getVerificationDocument")]
    pub fn get_verification_document(&mut self, url: &str) -> Option<VerificationDocument> {
        get_verification_document(self, url)
    }
}