rdml-qpcr 0.1.1

Read, write, and validate RDML (Real-time PCR Data Markup Language) qPCR data files
Documentation
//! Fluorescent dyes (root-level master element `dye`).

use serde::{Deserialize, Serialize};

use crate::enums::DyeChemistry;
use crate::types::{DyeRef, Id};

/// A fluorescent reporter dye. Every [`Target`](crate::Target) must
/// reference a dye; the target–dye association is what allows software
/// to reconstruct a multiplex plate.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Dye {
    /// Unique id this dye is referenced by, e.g. `FAM` or `SYBR`.
    pub id: Id,
    /// Free-text description.
    #[serde(skip_serializing_if = "Option::is_none", default)]
    pub description: Option<String>,
    /// The monitoring chemistry of this dye. *(RDML ≥ 1.3)*
    #[serde(
        rename = "dyeChemistry",
        skip_serializing_if = "Option::is_none",
        default
    )]
    pub chemistry: Option<DyeChemistry>,
    /// Factor used in the calculation of `Ncopy`. Different reaction mixes
    /// may require a slightly different factor. If absent, consumers use
    /// 0.10 for probes, 1.5 for SYBR Green (with a different calculation
    /// including amplicon length), and 0.04 for Eva Green.
    /// *(RDML 1.4, candidate recommendation)*
    #[serde(rename = "nCopyFact", skip_serializing_if = "Option::is_none", default)]
    pub n_copy_fact: Option<f64>,
    /// Nanomolar (nmol/l) concentration of the dye; e.g. SYBR Green is
    /// typically used at 400.0 nmol/l. If absent, consumers assume 400.0.
    /// *(RDML 1.4, candidate recommendation)*
    #[serde(rename = "dyeConc", skip_serializing_if = "Option::is_none", default)]
    pub dye_conc: Option<f64>,
}

impl Dye {
    /// Creates a dye with the given id and no optional detail.
    #[must_use]
    pub fn new(id: Id) -> Self {
        Self {
            id,
            description: None,
            chemistry: None,
            n_copy_fact: None,
            dye_conc: None,
        }
    }

    /// A typed reference to this dye, for use in [`Target::dye_id`](crate::Target::dye_id).
    #[must_use]
    pub fn reference(&self) -> DyeRef {
        self.id.clone().into()
    }
}