use super::{
error, LoadableDevice, MeasurementMetadata, MeasurementResults,
ProfileDescription, Result, ResultDescription, SampleMetadata,
Sampling, UnitDescription, Uuid,
};
use indexmap::IndexSet;
use snafu::OptionExt;
pub struct Sample<'a> {
pub device: &'a dyn LoadableDevice,
pub sample_id: Uuid,
}
pub trait GetSampleRef<'a> {
fn get_sample_ref(&'a self, sample_id: Uuid) -> Sample<'a>;
}
impl<'a> GetSampleRef<'a> for dyn LoadableDevice {
fn get_sample_ref(&'a self, sample_id: Uuid) -> Sample<'a> {
Sample {
device: self,
sample_id,
}
}
}
impl<'a> Sample<'a> {
pub fn get_measurement_ref(
&'a self,
measurement_index: usize,
) -> Measurement<'a> {
Measurement {
device: self.device,
sample_id: self.sample_id,
measurement_index,
}
}
pub fn load_metadata(&self) -> Result<SampleMetadata> {
self.device.load_sample_metadata(self.sample_id)
}
pub fn load_measurement_index(&self) -> Result<IndexSet<usize>> {
self.device.load_measurement_index(self.sample_id)
}
pub fn load_profile(&'a self) -> Result<ProfileDescription> {
self.device.load_profile(self.load_metadata()?.profile)
}
pub fn load_sampling(&'a self) -> Result<Sampling> {
self.device.load_sampling(&self.load_profile()?.sampling_id)
}
}
pub struct Measurement<'a> {
pub device: &'a dyn LoadableDevice,
pub sample_id: Uuid,
pub measurement_index: usize,
}
impl<'a> Measurement<'a> {
pub fn get_sample_ref(&'a self) -> Sample<'a> {
Sample {
device: self.device,
sample_id: self.sample_id,
}
}
pub fn load_metadata(&self) -> Result<MeasurementMetadata> {
self.device.load_measurement_metadata(
self.sample_id,
self.measurement_index,
)
}
pub fn load_results(&self) -> Result<MeasurementResults> {
self.device
.load_results(self.sample_id, self.measurement_index)
}
}
pub struct MeasurementResult<'a> {
pub device: &'a dyn LoadableDevice,
pub sample_id: Uuid,
pub measurement_index: usize,
pub result_id: String,
}
impl<'a> MeasurementResult<'a> {
pub fn load(&'a self) -> Result<f64> {
match self
.device
.load_results(self.sample_id, self.measurement_index)?
.get(&self.result_id)
{
Some(Some(value)) => Ok(*value),
None | Some(None) => error::NotFound {
kind: "result",
id: self.result_id.to_string(),
}
.fail()?,
}
}
pub fn get_measurement_ref(&'a self) -> Measurement<'a> {
Measurement {
device: self.device,
sample_id: self.sample_id,
measurement_index: self.measurement_index,
}
}
pub fn get_sample_ref(&'a self) -> Sample<'a> {
Sample {
device: self.device,
sample_id: self.sample_id,
}
}
pub fn load_result_description(&self) -> Result<ResultDescription> {
Ok(self
.get_sample_ref()
.load_sampling()?
.results
.get(&self.result_id)
.context(error::NotFound {
kind: "result",
id: self.result_id.to_string(),
})?
.clone())
}
pub fn load_unit(&self) -> Result<UnitDescription> {
let unit_id = self.load_result_description()?.unit.unit_id;
self.device.load_unit(&unit_id)
}
}