sfs_core/input/sample/
population.rs

1//! Sample population.
2
3use std::fmt;
4
5use indexmap::IndexSet;
6
7/// A population for a sample.
8#[derive(Clone, Debug, Eq, Hash, PartialEq)]
9pub enum Population {
10    /// Named population.
11    Named(String),
12    /// Unnamed population.
13    Unnamed,
14}
15
16impl<S> From<Option<S>> for Population
17where
18    S: ToString,
19{
20    fn from(population: Option<S>) -> Self {
21        match population {
22            Some(population) => Self::Named(population.to_string()),
23            None => Self::Unnamed,
24        }
25    }
26}
27
28impl fmt::Display for Population {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        match self {
31            Population::Named(name) => write!(f, "{name}"),
32            Population::Unnamed => f.write_str("[unnamed]"),
33        }
34    }
35}
36
37/// A numeric id for a sample population.
38#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
39pub struct Id(pub usize);
40
41impl From<Id> for usize {
42    fn from(id: Id) -> Self {
43        id.0
44    }
45}
46
47#[derive(Clone, Debug, Default, Eq, PartialEq)]
48pub(super) struct Map(IndexSet<Population>);
49
50impl Map {
51    pub fn get(&self, name: &Population) -> Option<Id> {
52        self.0.get_index_of(name).map(Id)
53    }
54
55    pub fn get_or_insert(&mut self, name: Population) -> Id {
56        self.get(&name).unwrap_or_else(|| self.insert(name))
57    }
58
59    pub fn insert(&mut self, name: Population) -> Id {
60        Id(self.0.insert_full(name).0)
61    }
62}