use super::{VerificationCategory, VerificationError, VerificationErrorImpl, VerificationPeriod};
use serde::{
de::{Deserialize as Deserialize2, Deserializer, Error},
Deserialize,
};
#[derive(Deserialize, Debug, Clone)]
pub struct VerificationMetaDataList(Vec<VerificationMetaData>);
#[derive(Deserialize, Debug, Clone)]
pub struct VerificationMetaData {
id: String,
name: String,
algorithm: String,
description: String,
#[serde(deserialize_with = "deserialize_string_to_period")]
period: VerificationPeriod,
#[serde(deserialize_with = "deserialize_string_to_category")]
category: VerificationCategory,
}
impl VerificationMetaDataList {
pub fn load(data: &str) -> Result<Self, VerificationError> {
serde_json::from_str(data)
.map_err(|e| VerificationErrorImpl::LoadMetadata { source: e })
.map_err(VerificationError::from)
}
pub fn load_period(data: &str, period: &VerificationPeriod) -> Result<Self, VerificationError> {
Ok(Self(
Self::load(data)
.map_err(|e| VerificationErrorImpl::LoadMetadataPeriod {
period: *period,
source: Box::new(e),
})?
.0
.iter()
.filter(|&m| m.period() == period)
.cloned()
.collect::<Vec<VerificationMetaData>>(),
))
}
pub fn meta_data_from_id(&self, id: &str) -> Option<&VerificationMetaData> {
self.0.iter().find(|e| e.id == id)
}
pub fn id_list(&self) -> Vec<&str> {
self.0.iter().map(|e| e.id.as_str()).collect::<Vec<_>>()
}
pub fn id_list_for_period(&self, period: &VerificationPeriod) -> Vec<&str> {
self.0
.iter()
.filter(|e| &e.period == period)
.map(|e| e.id.as_str())
.collect::<Vec<_>>()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn get(&self, id: &str) -> Option<&VerificationMetaData> {
self.iter().find(|&e| e.id == id)
}
pub fn iter(&'_ self) -> std::slice::Iter<'_, VerificationMetaData> {
self.0.iter()
}
pub fn list(&self) -> &[VerificationMetaData] {
&self.0
}
}
impl VerificationMetaData {
pub fn id(&self) -> &str {
&self.id
}
pub fn name(&self) -> &str {
&self.name
}
pub fn algorithm(&self) -> &str {
&self.algorithm
}
pub fn description(&self) -> &str {
&self.description
}
pub fn period(&self) -> &VerificationPeriod {
&self.period
}
pub fn category(&self) -> &VerificationCategory {
&self.category
}
}
fn deserialize_string_to_period<'de, D>(deserializer: D) -> Result<VerificationPeriod, D::Error>
where
D: Deserializer<'de>,
{
let buf = String::deserialize(deserializer)?;
VerificationPeriod::try_from(buf.as_str()).map_err(|e| Error::custom(e.to_string()))
}
fn deserialize_string_to_category<'de, D>(deserializer: D) -> Result<VerificationCategory, D::Error>
where
D: Deserializer<'de>,
{
let buf = String::deserialize(deserializer)?;
VerificationCategory::try_from(buf.as_str()).map_err(|e| Error::custom(e.to_string()))
}
#[cfg(test)]
mod test {
use super::*;
use crate::config::test::CONFIG_TEST;
#[test]
fn test_load() {
let metadata_res = VerificationMetaDataList::load(CONFIG_TEST.get_verification_list_str());
assert!(metadata_res.is_ok());
let metadata = metadata_res.unwrap();
assert!(!metadata.is_empty());
assert!(metadata.meta_data_from_id("01.01").is_some())
}
}