use crate::types::{QldbExtractError, QldbExtractResult};
use ion_binary_rs::IonValue;
use std::{collections::HashMap, convert::TryFrom};
#[derive(Clone, Debug, PartialEq)]
pub struct Document {
document: HashMap<String, IonValue>,
}
impl TryFrom<IonValue> for Document {
type Error = QldbExtractError;
fn try_from(value: IonValue) -> Result<Self, Self::Error> {
match value {
IonValue::Struct(value) => Ok(Document { document: value }),
_ => Err(QldbExtractError::NotADocument(value)),
}
}
}
impl Document {
pub fn get_value<T>(&self, name: &str) -> QldbExtractResult<T>
where
T: TryFrom<IonValue> + Send + Sync + Clone,
<T as TryFrom<IonValue>>::Error: std::error::Error + Send + Sync + 'static,
{
let element = self
.document
.get(name)
.ok_or_else(|| QldbExtractError::MissingProperty(name.to_string()))?;
match T::try_from(element.clone()) {
Ok(result) => Ok(result),
Err(err) => Err(QldbExtractError::BadDataType(Box::new(err))),
}
}
pub fn get(&self, name: &str) -> Option<&IonValue> {
self.document.get(name)
}
pub fn get_optional_value<T>(&self, name: &str) -> QldbExtractResult<Option<T>>
where
T: TryFrom<IonValue> + Send + Sync + Clone,
<T as TryFrom<IonValue>>::Error: std::error::Error + Send + Sync + 'static,
{
let element = match self.document.get(name) {
Some(elem) => elem,
None => return Ok(None),
};
match T::try_from(element.clone()) {
Ok(result) => Ok(Some(result)),
Err(err) => Err(QldbExtractError::BadDataType(Box::new(err))),
}
}
}