1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// feature_index.rs
/// Defines the canonical feature space used by `Scdata`.
///
/// # Example
///
/// ```no_run
/// use std::collections::HashMap;
/// use scdata::FeatureIndex;
///
/// struct SimpleIndex {
/// names: Vec<String>,
/// ids: HashMap<String, u64>,
/// }
///
/// impl SimpleIndex {
/// fn new(names: Vec<&str>) -> Self {
/// let names: Vec<String> = names.into_iter().map(|s| s.to_string()).collect();
/// let ids = names
/// .iter()
/// .enumerate()
/// .map(|(i, n)| (n.clone(), i as u64))
/// .collect();
/// Self { names, ids }
/// }
/// }
///
/// impl FeatureIndex for SimpleIndex {
/// fn feature_name(&self, feature_id: u64) -> &str {
/// &self.names[feature_id as usize]
/// }
///
/// fn feature_id(&self, name: &str) -> Option<u64> {
/// self.ids.get(name).copied()
/// }
///
/// fn ordered_feature_ids(&self) -> Vec<u64> {
/// (0..self.names.len() as u64).collect()
/// }
///
/// fn to_10x_feature_line(&self, feature_id: u64) -> String {
/// let name = self.feature_name(feature_id);
/// format!("{name}\t{name}\tGene Expression")
/// }
/// }
///
/// let index = SimpleIndex::new(vec!["GeneA", "GeneB"]);
/// assert_eq!(index.feature_id("GeneA"), Some(0));
/// assert_eq!(index.feature_name(1), "GeneB");
/// ```