use super::ValidationInputError;
use crate::document::read_document;
use molframe_validate::{ReferenceDistribution, ReferenceLibrary};
use serde::Deserialize;
use std::path::Path;
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct Document {
library: Identity,
distribution: Vec<Distribution>,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct Identity {
id: Box<str>,
version: Box<str>,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct Distribution {
name: Box<str>,
edges: Option<Vec<f64>>,
x_edges: Option<Vec<f64>>,
y_edges: Option<Vec<f64>>,
weights: Vec<f64>,
}
impl Distribution {
fn build(self) -> Result<ReferenceDistribution, ValidationInputError> {
match (self.edges, self.x_edges, self.y_edges) {
(Some(edges), None, None) => Ok(ReferenceDistribution::histogram(
self.name,
edges,
self.weights,
)?),
(None, Some(x_edges), Some(y_edges)) => Ok(ReferenceDistribution::grid(
self.name,
x_edges,
y_edges,
self.weights,
)?),
_ => Err(ValidationInputError::invalid(
format!("distribution {}", self.name),
"give either `edges` for a histogram or both `x_edges` and `y_edges` for a grid",
)),
}
}
}
pub fn read_reference_library(
path: impl AsRef<Path>,
) -> Result<ReferenceLibrary, ValidationInputError> {
let document: Document = read_document(path.as_ref())?;
let distributions = document
.distribution
.into_iter()
.map(Distribution::build)
.collect::<Result<Vec<_>, _>>()?;
Ok(ReferenceLibrary::new(
document.library.id,
document.library.version,
distributions,
)?)
}
#[cfg(test)]
#[path = "library_tests.rs"]
mod tests;