pub mod dpcr;
pub mod dye;
pub mod experiment;
pub mod people;
pub mod protocol;
pub mod sample;
pub mod target;
use serde::{Deserialize, Serialize};
use crate::types::DateTime;
pub use dpcr::{PartitionData, Partitions};
pub use dye::Dye;
pub use experiment::{
AmpPoint, Data, DataCollectionSoftware, Experiment, MeltPoint, PcrFormat, PlateLayout, React,
Run,
};
pub use people::{Documentation, Experimenter, RdmlId};
pub use protocol::{
GradientStep, LoopStep, PauseStep, Step, StepKind, TemperatureStep, ThermalCyclingConditions,
};
pub use sample::{
Annotation, CdnaSynthesisMethod, Quantity, Sample, SampleTypeEntry, TemplateQuantity,
};
pub use target::{CommercialAssay, Oligo, Sequences, Target, XRef};
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct Rdml {
#[serde(rename = "dateMade", skip_serializing_if = "Option::is_none", default)]
pub date_made: Option<DateTime>,
#[serde(
rename = "dateUpdated",
skip_serializing_if = "Option::is_none",
default
)]
pub date_updated: Option<DateTime>,
#[serde(rename = "id", skip_serializing_if = "Vec::is_empty", default)]
pub ids: Vec<RdmlId>,
#[serde(
rename = "experimenter",
skip_serializing_if = "Vec::is_empty",
default
)]
pub experimenters: Vec<Experimenter>,
#[serde(
rename = "documentation",
skip_serializing_if = "Vec::is_empty",
default
)]
pub documentations: Vec<Documentation>,
#[serde(rename = "dye", skip_serializing_if = "Vec::is_empty", default)]
pub dyes: Vec<Dye>,
#[serde(rename = "sample", skip_serializing_if = "Vec::is_empty", default)]
pub samples: Vec<Sample>,
#[serde(rename = "target", skip_serializing_if = "Vec::is_empty", default)]
pub targets: Vec<Target>,
#[serde(
rename = "thermalCyclingConditions",
skip_serializing_if = "Vec::is_empty",
default
)]
pub thermal_cycling_conditions: Vec<ThermalCyclingConditions>,
#[serde(rename = "experiment", skip_serializing_if = "Vec::is_empty", default)]
pub experiments: Vec<Experiment>,
}
impl Rdml {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn sample(&self, id: impl AsRef<str>) -> Option<&Sample> {
let id = id.as_ref();
self.samples.iter().find(|s| s.id.as_str() == id)
}
pub fn target(&self, id: impl AsRef<str>) -> Option<&Target> {
let id = id.as_ref();
self.targets.iter().find(|t| t.id.as_str() == id)
}
pub fn dye(&self, id: impl AsRef<str>) -> Option<&Dye> {
let id = id.as_ref();
self.dyes.iter().find(|d| d.id.as_str() == id)
}
pub fn experimenter(&self, id: impl AsRef<str>) -> Option<&Experimenter> {
let id = id.as_ref();
self.experimenters.iter().find(|e| e.id.as_str() == id)
}
pub fn documentation(&self, id: impl AsRef<str>) -> Option<&Documentation> {
let id = id.as_ref();
self.documentations.iter().find(|d| d.id.as_str() == id)
}
pub fn thermal_cycling(&self, id: impl AsRef<str>) -> Option<&ThermalCyclingConditions> {
let id = id.as_ref();
self.thermal_cycling_conditions
.iter()
.find(|t| t.id.as_str() == id)
}
pub fn experiment(&self, id: impl AsRef<str>) -> Option<&Experiment> {
let id = id.as_ref();
self.experiments.iter().find(|e| e.id.as_str() == id)
}
pub fn reactions(&self) -> impl Iterator<Item = ReactionContext<'_>> {
self.experiments.iter().flat_map(|experiment| {
experiment.runs.iter().flat_map(move |run| {
run.reacts.iter().map(move |react| ReactionContext {
experiment,
run,
react,
})
})
})
}
pub fn data_entries(&self) -> impl Iterator<Item = DataContext<'_>> {
self.reactions().flat_map(|ctx| {
ctx.react.data.iter().map(move |data| DataContext {
experiment: ctx.experiment,
run: ctx.run,
react: ctx.react,
data,
})
})
}
}
#[derive(Debug, Clone, Copy)]
pub struct ReactionContext<'a> {
pub experiment: &'a Experiment,
pub run: &'a Run,
pub react: &'a React,
}
#[derive(Debug, Clone, Copy)]
pub struct DataContext<'a> {
pub experiment: &'a Experiment,
pub run: &'a Run,
pub react: &'a React,
pub data: &'a Data,
}