use serde::{Deserialize, Serialize};
use crate::enums::TargetType;
use crate::types::{DocumentationRef, DyeRef, Id, Sequence, TargetRef};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Target {
pub id: Id,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub description: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub documentation: Vec<DocumentationRef>,
#[serde(rename = "xRef", skip_serializing_if = "Vec::is_empty", default)]
pub x_refs: Vec<XRef>,
#[serde(rename = "type")]
pub target_type: TargetType,
#[serde(
rename = "amplificationEfficiencyMethod",
skip_serializing_if = "Option::is_none",
default
)]
pub amplification_efficiency_method: Option<String>,
#[serde(
rename = "amplificationEfficiency",
skip_serializing_if = "Option::is_none",
default
)]
pub amplification_efficiency: Option<f64>,
#[serde(
rename = "amplificationEfficiencySE",
skip_serializing_if = "Option::is_none",
default
)]
pub amplification_efficiency_se: Option<f64>,
#[serde(
rename = "meltingTemperature",
skip_serializing_if = "Option::is_none",
default
)]
pub melting_temperature: Option<f64>,
#[serde(
rename = "detectionLimit",
skip_serializing_if = "Option::is_none",
default
)]
pub detection_limit: Option<f64>,
#[serde(rename = "dyeId")]
pub dye_id: DyeRef,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub sequences: Option<Sequences>,
#[serde(
rename = "commercialAssay",
skip_serializing_if = "Option::is_none",
default
)]
pub commercial_assay: Option<CommercialAssay>,
}
impl Target {
#[must_use]
pub fn new(id: Id, target_type: TargetType, dye_id: DyeRef) -> Self {
Self {
id,
description: None,
documentation: Vec::new(),
x_refs: Vec::new(),
target_type,
amplification_efficiency_method: None,
amplification_efficiency: None,
amplification_efficiency_se: None,
melting_temperature: None,
detection_limit: None,
dye_id,
sequences: None,
commercial_assay: None,
}
}
#[must_use]
pub fn reference(&self) -> TargetRef {
self.id.clone().into()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
pub struct XRef {
#[serde(skip_serializing_if = "Option::is_none", default)]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub id: Option<String>,
}
impl XRef {
pub fn new(name: impl Into<String>, id: impl Into<String>) -> Self {
Self {
name: Some(name.into()),
id: Some(id.into()),
}
}
}
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct Sequences {
#[serde(
rename = "forwardPrimer",
skip_serializing_if = "Option::is_none",
default
)]
pub forward_primer: Option<Oligo>,
#[serde(
rename = "reversePrimer",
skip_serializing_if = "Option::is_none",
default
)]
pub reverse_primer: Option<Oligo>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub probe1: Option<Oligo>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub probe2: Option<Oligo>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub amplicon: Option<Oligo>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Oligo {
#[serde(
rename = "threePrimeTag",
skip_serializing_if = "Option::is_none",
default
)]
pub three_prime_tag: Option<String>,
#[serde(
rename = "fivePrimeTag",
skip_serializing_if = "Option::is_none",
default
)]
pub five_prime_tag: Option<String>,
pub sequence: Sequence,
#[serde(rename = "oligoConc", skip_serializing_if = "Option::is_none", default)]
pub oligo_conc: Option<f64>,
}
impl Oligo {
#[must_use]
pub fn new(sequence: Sequence) -> Self {
Self {
three_prime_tag: None,
five_prime_tag: None,
sequence,
oligo_conc: None,
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CommercialAssay {
pub company: String,
#[serde(rename = "orderNumber")]
pub order_number: String,
}
impl CommercialAssay {
pub fn new(company: impl Into<String>, order_number: impl Into<String>) -> Self {
Self {
company: company.into(),
order_number: order_number.into(),
}
}
}