///|
pub fn Feature::to_zero_based_start(self : Feature) -> Int {
self.start - 1
}
///|
pub fn Feature::to_half_open_end(self : Feature) -> Int {
self.end
}
///|
pub fn Feature::span(self : Feature) -> Span {
{ seqid: self.seqid, start: self.start, end: self.end }
}
///|
pub fn Span::length(self : Span) -> Int {
self.end - self.start + 1
}
///|
pub fn Span::contains(self : Span, position~ : Int) -> Bool {
self.start <= position && position <= self.end
}
///|
pub fn Span::overlaps(self : Span, other : Span) -> Bool {
self.seqid == other.seqid &&
self.start <= other.end &&
self.end >= other.start
}
///|
pub fn Span::overlap_length(self : Span, other : Span) -> Int {
if !self.overlaps(other) {
0
} else {
let start = if self.start > other.start { self.start } else { other.start }
let end = if self.end < other.end { self.end } else { other.end }
end - start + 1
}
}
///|
pub fn Span::to_bed_start(self : Span) -> Int {
self.start - 1
}
///|
pub fn Span::to_bed_end(self : Span) -> Int {
self.end
}
///|
pub fn Span::shift(self : Span, offset : Int) -> Span {
{ seqid: self.seqid, start: self.start + offset, end: self.end + offset }
}
///|
pub fn Span::expand(self : Span, bases : Int) -> Span {
let start = if self.start - bases < 1 { 1 } else { self.start - bases }
{ seqid: self.seqid, start, end: self.end + bases }
}
///|
pub fn Span::distance_to(self : Span, other : Span) -> Int? {
if self.seqid != other.seqid {
None
} else if self.overlaps(other) {
Some(0)
} else if self.end < other.start {
Some(other.start - self.end)
} else {
Some(self.start - other.end)
}
}
///|
pub fn Span::to_region_string(self : Span) -> String {
"\{self.seqid}:\{self.start}-\{self.end}"
}
///|
pub fn Feature::region_string(self : Feature) -> String {
self.span().to_region_string()
}