From 381bdf14a91a97c6960f98504df8db5145e993f5 Mon Sep 17 00:00:00 2001 From: "Kevin R. Thornton" Date: Wed, 15 Jun 2022 12:56:57 -0700 Subject: [PATCH] Document builder.rs (#113) * Make API to add migration more convient. --- src/builder.rs | 195 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 182 insertions(+), 13 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 31cdc45a..dd0edfcc 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1,3 +1,4 @@ +#![warn(missing_docs)] use crate::specification::Deme; use crate::specification::GenerationTime; use crate::specification::Graph; @@ -10,12 +11,27 @@ use crate::specification::UnresolvedDemeHistory; use crate::specification::UnresolvedEpoch; use crate::DemesError; +/// This type allows building a [`Graph`](crate::Graph) using code +/// rather then using text input. +/// +/// # Notes +/// +/// * A "builder" in rust will never be as convenient +/// as one in, say, Python or Juilia. +/// The lack of a rust REPL and the strong type checking +/// are the primary reasons. +/// * All error checks are delayed until resolution. pub struct GraphBuilder { graph: Graph, } impl GraphBuilder { - // public API + /// Constructor + /// + /// # Returns + /// + /// This function returns an "builder" containing an unresolved + /// [`Graph`](crate::Graph). pub fn new( time_units: TimeUnits, generation_time: Option, @@ -26,18 +42,29 @@ impl GraphBuilder { } } + /// Construct a builder with time units in generations. + /// + /// This function works by calling [`GraphBuilder::new`](crate::GraphBuilder::new). pub fn new_generations(defaults: Option) -> Self { Self { graph: Graph::new(TimeUnits::Generations, None, defaults), } } - pub fn resolve(self) -> Result { - let mut builder = self; - builder.graph.resolve()?; - Ok(builder.graph) - } - + /// Add a [`Deme`](crate::Deme) to the graph. + /// + /// # Examples + /// + /// ``` + /// let start_size = demes::DemeSize::from(100.); + /// let epoch = demes::UnresolvedEpoch{start_size: Some(start_size), ..Default::default()}; + /// let history = demes::UnresolvedDemeHistory::default(); + /// let mut b = demes::GraphBuilder::new_generations(None); + /// b.add_deme("A", vec![epoch], history, Some("this is deme A")); + /// b.resolve().unwrap(); + /// ``` + /// + /// # Notes pub fn add_deme( &mut self, name: &str, @@ -49,28 +76,170 @@ impl GraphBuilder { self.graph.add_deme(ptr); } - pub fn add_migration( + /// Add an asymmetric migration + /// + /// # Examples + /// + /// ``` + /// let start_size = demes::DemeSize::from(100.); + /// let epoch = demes::UnresolvedEpoch{start_size: Some(start_size), ..Default::default()}; + /// let history = demes::UnresolvedDemeHistory::default(); + /// let mut b = demes::GraphBuilder::new_generations(None); + /// b.add_deme("A", vec![epoch], history.clone(), Some("this is deme A")); + /// b.add_deme("B", vec![epoch], history, Some("this is deme B")); + /// b.add_asymmetric_migration(Some("A"), + /// Some("B"), + /// Some(demes::MigrationRate::from(1e-4)), + /// None, // Using None for the times + /// // will mean continuous migration for the + /// // duration for which the demes coexist. + /// None); + /// b.resolve().unwrap(); + /// ``` + pub fn add_asymmetric_migration( + &mut self, + source: Option, + dest: Option, + rate: Option, + start_time: Option