grass_runtime/record/
bed5.rs1use 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> {}