noodles_vcf/variant/record_buf/samples/
series.rs

1use std::io;
2
3use super::sample::Value;
4use crate::Header;
5
6/// A variant record samples buffer series.
7pub struct Series<'s> {
8    name: &'s str,
9    values: &'s [Vec<Option<Value>>],
10    i: usize,
11}
12
13impl<'s> Series<'s> {
14    pub(super) fn new(name: &'s str, values: &'s [Vec<Option<Value>>], i: usize) -> Self {
15        Self { name, values, i }
16    }
17
18    /// Returns the value at the given index.
19    pub fn get(&self, i: usize) -> Option<Option<&Value>> {
20        self.values
21            .get(i)
22            .map(|sample| sample.get(self.i).and_then(|value| value.as_ref()))
23    }
24}
25
26impl crate::variant::record::samples::Series for Series<'_> {
27    fn name<'a, 'h: 'a>(&'a self, _: &'h Header) -> io::Result<&'a str> {
28        Ok(self.name)
29    }
30
31    fn get<'a, 'h: 'a>(
32        &'a self,
33        _: &'h Header,
34        i: usize,
35    ) -> Option<Option<io::Result<crate::variant::record::samples::series::Value<'a>>>> {
36        self.values.get(i).map(|sample| {
37            sample
38                .get(self.i)
39                .and_then(|value| value.as_ref().map(|v| Ok(v.into())))
40        })
41    }
42
43    fn iter<'a, 'h: 'a>(
44        &'a self,
45        _: &'h Header,
46    ) -> Box<
47        dyn Iterator<Item = io::Result<Option<crate::variant::record::samples::series::Value<'a>>>>
48            + 'a,
49    > {
50        Box::new(self.values.iter().map(|sample| {
51            Ok(sample
52                .get(self.i)
53                .and_then(|value| value.as_ref().map(|v| v.into())))
54        }))
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61    use crate::variant::record::samples::{keys::key, Series as _};
62
63    #[test]
64    fn test_name() {
65        let header = Header::default();
66        let series = Series::new(key::GENOTYPE, &[], 0);
67        assert!(matches!(
68            series.name(&header),
69            Ok(name) if name == key::GENOTYPE
70        ));
71    }
72
73    #[test]
74    fn test_get() {
75        let values = [
76            vec![Some(Value::from("0|0")), Some(Value::from(7))],
77            vec![Some(Value::from("1/1"))],
78            vec![],
79        ];
80
81        let series = Series::new(key::GENOTYPE, &values, 0);
82        assert_eq!(series.get(0), Some(Some(&Value::from("0|0"))));
83        assert_eq!(series.get(1), Some(Some(&Value::from("1/1"))));
84        assert_eq!(series.get(2), Some(None));
85        assert_eq!(series.get(3), None);
86
87        let series = Series::new(key::CONDITIONAL_GENOTYPE_QUALITY, &values, 1);
88        assert_eq!(series.get(0), Some(Some(&Value::from(7))));
89        assert_eq!(series.get(1), Some(None));
90        assert_eq!(series.get(2), Some(None));
91        assert_eq!(series.get(3), None);
92    }
93}