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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
use std::{
fmt,
ops::{Bound, RangeBounds},
};
/// An interval.
pub type Interval = (Bound<i32>, Bound<i32>);
/// A mapped region.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Mapped {
name: String,
start: Bound<i32>,
end: Bound<i32>,
}
impl Mapped {
/// Creates a mapped region.
///
/// # Examples
///
/// ```
/// use noodles_core::Region;
/// assert!(Region::mapped("sq0", 5..=8).as_mapped().is_some());
/// ```
pub fn new<S, B>(name: S, interval: B) -> Self
where
S: Into<String>,
B: RangeBounds<i32>,
{
Self {
name: name.into(),
start: interval.start_bound().cloned(),
end: interval.end_bound().cloned(),
}
}
/// Returns the reference sequence name.
///
/// # Examples
///
/// ```
/// use noodles_core::Region;
///
/// assert_eq!(
/// Region::mapped("sq0", 5..=8).as_mapped().map(|r| r.name()),
/// Some("sq0")
/// );
/// ```
pub fn name(&self) -> &str {
&self.name
}
/// Returns the start position of the region (1-based).
///
/// # Examples
///
/// ```
/// # use std::ops::Bound;
/// use noodles_core::Region;
///
/// assert_eq!(
/// Region::mapped("sq0", 5..=8).as_mapped().map(|r| r.start()),
/// Some(Bound::Included(5))
/// );
/// ```
pub fn start(&self) -> Bound<i32> {
self.start
}
/// Returns the end position of the region (1-based).
///
/// # Examples
///
/// ```
/// # use std::ops::Bound;
/// use noodles_core::Region;
///
/// assert_eq!(
/// Region::mapped("sq0", 5..=8).as_mapped().map(|r| r.end()),
/// Some(Bound::Included(8))
/// );
/// ```
pub fn end(&self) -> Bound<i32> {
self.end
}
/// Returns the start and end positions as an interval.
///
/// # Examples
///
/// ```
/// # use std::ops::Bound;
/// use noodles_core::Region;
///
/// assert_eq!(
/// Region::mapped("sq0", 5..=8).as_mapped().map(|r| r.interval()),
/// Some((Bound::Included(5), Bound::Included(8)))
/// );
/// ```
pub fn interval(&self) -> Interval {
(self.start, self.end)
}
}
impl fmt::Display for Mapped {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.interval() {
(Bound::Unbounded, Bound::Unbounded) => write!(f, "{}", self.name()),
(Bound::Included(s), Bound::Unbounded) => write!(f, "{}:{}", self.name(), s),
(Bound::Included(s), Bound::Included(e)) => write!(f, "{}:{}-{}", self.name(), s, e),
_ => todo!(),
}
}
}