use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use super::reader_auth::ReaderAuth;
use crate::models::{
data_retrieval::common::{DataElementIdentifier, DocType, NameSpace},
BytesCbor,
};
const DEVICE_REQUEST_VERSION: &str = "1.0";
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DeviceRequest {
version: String,
doc_requests: Vec<DocRequest>,
}
impl DeviceRequest {
pub fn new(doc_requests: Vec<DocRequest>) -> Self {
Self {
version: DEVICE_REQUEST_VERSION.to_owned(),
doc_requests,
}
}
pub(crate) fn find_by_doc_type(&self, doc_type: &DocType) -> Option<&DocRequest> {
self.doc_requests
.iter()
.find(|doc_request| &doc_request.items_request.0.inner.doc_type == doc_type)
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DocRequest {
items_request: ItemsRequestBytes,
#[serde(skip_serializing_if = "Option::is_none")]
reader_auth: Option<ReaderAuth>,
}
impl DocRequest {
pub(crate) fn name_spaces(&self) -> &NameSpaces {
&self.items_request.0.inner.name_spaces
}
pub fn builder(doc_type: DocType) -> DocRequestBuilder {
DocRequestBuilder::new(doc_type)
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct ItemsRequestBytes(BytesCbor<ItemsRequest>);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ItemsRequest {
doc_type: DocType,
name_spaces: NameSpaces,
#[serde(skip_serializing_if = "Option::is_none")]
request_info: Option<HashMap<String, ciborium::Value>>,
}
impl From<ItemsRequest> for ItemsRequestBytes {
fn from(value: ItemsRequest) -> Self {
Self(value.into())
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct NameSpaces(pub(crate) HashMap<NameSpace, DataElements>);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct DataElements(pub(crate) HashMap<DataElementIdentifier, IntentToRetain>);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct IntentToRetain(bool);
impl From<bool> for IntentToRetain {
fn from(value: bool) -> Self {
Self(value)
}
}
#[derive(Debug)]
pub struct DocRequestBuilder {
doc_type: DocType,
name_spaces: NameSpaces,
request_info: Option<HashMap<String, ciborium::Value>>,
reader_auth: Option<ReaderAuth>,
}
impl DocRequestBuilder {
pub fn new(doc_type: DocType) -> Self {
Self {
doc_type,
name_spaces: NameSpaces(HashMap::new()),
request_info: None,
reader_auth: None,
}
}
pub fn add_name_space(
mut self,
name_space: NameSpace,
data_elements: HashMap<DataElementIdentifier, IntentToRetain>,
) -> Self {
self.name_spaces
.0
.insert(name_space, DataElements(data_elements));
self
}
pub fn add_data_element(
mut self,
name_space: NameSpace,
data_element_identifier: DataElementIdentifier,
intent_to_retain: IntentToRetain,
) -> Self {
self.name_spaces
.0
.entry(name_space)
.or_insert_with(|| DataElements(HashMap::new()))
.0
.insert(data_element_identifier, intent_to_retain);
self
}
pub fn add_request_info(mut self, request_info: HashMap<String, ciborium::Value>) -> Self {
self.request_info = Some(request_info);
self
}
pub fn add_reader_auth(mut self, reader_auth: ReaderAuth) -> Self {
self.reader_auth = Some(reader_auth);
self
}
pub fn build(self) -> DocRequest {
let items_request = ItemsRequest {
doc_type: self.doc_type,
name_spaces: self.name_spaces,
request_info: self.request_info,
};
DocRequest {
items_request: items_request.into(),
reader_auth: self.reader_auth,
}
}
}