noodles_bcf/record/samples/
sample.rs

1use std::io;
2
3use noodles_vcf::{self as vcf, variant::record::samples::series::Value};
4
5use super::Samples;
6
7/// A BCF record sample.
8pub struct Sample<'r> {
9    samples: &'r Samples<'r>,
10    i: usize,
11}
12
13impl<'r> Sample<'r> {
14    pub(super) fn new(samples: &'r Samples<'r>, i: usize) -> Self {
15        Self { samples, i }
16    }
17}
18
19impl vcf::variant::record::samples::Sample for Sample<'_> {
20    fn get<'a, 'h: 'a>(
21        &'a self,
22        header: &'h vcf::Header,
23        key: &str,
24    ) -> Option<io::Result<Option<Value<'a>>>> {
25        for result in self.iter(header) {
26            match result {
27                Ok((k, v)) => {
28                    if k == key {
29                        return Some(Ok(v));
30                    }
31                }
32                Err(e) => return Some(Err(e)),
33            }
34        }
35
36        None
37    }
38
39    fn get_index<'a, 'h: 'a>(
40        &'a self,
41        header: &'h vcf::Header,
42        i: usize,
43    ) -> Option<io::Result<Option<Value<'a>>>> {
44        self.iter(header)
45            .nth(i)
46            .map(|result| result.map(|(_, value)| value))
47    }
48
49    fn iter<'a, 'h: 'a>(
50        &'a self,
51        header: &'h vcf::Header,
52    ) -> Box<dyn Iterator<Item = io::Result<(&'a str, Option<Value<'a>>)>> + 'a> {
53        let series = self.samples.series();
54
55        Box::new(series.map(|result| {
56            result.and_then(|series| {
57                let name = series.name(header)?;
58
59                let value = series
60                    .get(header, self.i)
61                    .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "missing value"))?
62                    .transpose()?;
63
64                Ok((name, value))
65            })
66        }))
67    }
68}