grass_runtime/record/
bed5.rs

1use std::{
2    fmt::Display,
3    io::{Result, Write},
4    ops::{Deref, DerefMut},
5    str::FromStr,
6};
7
8use crate::{
9    property::{Named, Parsable, RegionCore, Scored, Serializable, Stranded, Tagged},
10    ChrRef,
11};
12
13use super::{Bed4, RcCowString, ToSelfContained};
14
15#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
16pub struct Bed5<'a, T = f64> {
17    inner: Bed4<'a>,
18    pub score: Option<T>,
19}
20
21impl<'a, T> Deref for Bed5<'a, T> {
22    type Target = Bed4<'a>;
23
24    fn deref(&self) -> &Self::Target {
25        &self.inner
26    }
27}
28
29impl<'a> DerefMut for Bed5<'a> {
30    fn deref_mut(&mut self) -> &mut Self::Target {
31        &mut self.inner
32    }
33}
34
35impl<'a, T: Display> Serializable for Bed5<'a, T> {
36    fn dump<W: Write>(&self, mut fp: W) -> Result<()> {
37        self.inner.dump(&mut fp)?;
38        if let Some(score) = self.score.as_ref() {
39            write!(fp, "\t{}", score)?;
40        } else {
41            write!(fp, "\t.")?;
42        }
43        Ok(())
44    }
45}
46
47impl<'a, T: Display> Serializable for Option<Bed5<'a, T>> {
48    fn dump<W: Write>(&self, mut fp: W) -> Result<()> {
49        if let Some(inner) = self {
50            inner.dump(fp)
51        } else {
52            fp.write_all(b".\t.\t.\t.\t.")
53        }
54    }
55}
56
57impl<'a, T: FromStr> Parsable<'a> for Bed5<'a, T> {
58    fn parse(s: &'a str) -> Option<(Self, usize)> {
59        let (inner, mut start) = Bed4::parse(s)?;
60        if s[start..].starts_with('\t') {
61            start += 1;
62        }
63        let s = &s[start..];
64        let brk = memchr::memchr(b'\t', s.as_bytes()).unwrap_or(s.len());
65        let score = s[..brk].parse().ok();
66        Some((Self { inner, score }, start + brk))
67    }
68}
69
70impl<'a, S> Bed5<'a, S> {
71    pub fn new<T: RegionCore + Named<'a> + Scored<S>>(region: &T) -> Self
72    where
73        S: Default,
74    {
75        let score = region.score();
76        let inner = Bed4::new(region);
77        Self { inner, score }
78    }
79
80    #[inline(always)]
81    pub fn set_score(&mut self, score: S) {
82        self.score = Some(score);
83    }
84}
85
86impl<'a, S> RegionCore for Bed5<'a, S> {
87    #[inline(always)]
88    fn start(&self) -> u32 {
89        self.inner.start()
90    }
91    #[inline(always)]
92    fn end(&self) -> u32 {
93        self.inner.end()
94    }
95    #[inline(always)]
96    fn chrom(&self) -> ChrRef<'static> {
97        self.inner.chrom()
98    }
99}
100
101impl<'a, T: Clone> Scored<T> for Bed5<'a, T> {
102    #[inline(always)]
103    fn score(&self) -> Option<T> {
104        self.score.clone()
105    }
106}
107
108impl<'a, T> Stranded for Bed5<'a, T> {}
109
110impl<'a, T> Named<'a> for Bed5<'a, T> {
111    fn name(&self) -> &str {
112        self.inner.name()
113    }
114    fn to_cow(&self) -> RcCowString<'a> {
115        self.inner.to_cow()
116    }
117}
118
119impl<'a> ToSelfContained for Bed5<'a> {
120    type SelfContained = Bed5<'static>;
121    fn to_self_contained(&self) -> Self::SelfContained {
122        Bed5 {
123            inner: self.inner.to_self_contained(),
124            score: self.score,
125        }
126    }
127}
128
129impl<'a, T: Clone> Tagged<T> for Bed5<'a> {}