use super::GenomicInterval;
impl From<&crate::formats::bed::BedRecord> for GenomicInterval {
fn from(record: &crate::formats::bed::BedRecord) -> Self {
GenomicInterval {
chrom: record.chrom.clone(),
start: record.start,
end: record.end,
}
}
}
impl From<crate::formats::bed::BedRecord> for GenomicInterval {
fn from(record: crate::formats::bed::BedRecord) -> Self {
GenomicInterval {
chrom: record.chrom,
start: record.start,
end: record.end,
}
}
}
impl From<&crate::formats::vcf::VcfRecord> for GenomicInterval {
fn from(record: &crate::formats::vcf::VcfRecord) -> Self {
let start = if record.pos > 0 {
record.pos - 1
} else {
0
};
let end = start + record.reference.len() as u64;
GenomicInterval {
chrom: record.chrom.clone(),
start,
end,
}
}
}
impl From<crate::formats::vcf::VcfRecord> for GenomicInterval {
fn from(record: crate::formats::vcf::VcfRecord) -> Self {
let start = if record.pos > 0 {
record.pos - 1
} else {
0
};
let end = start + record.reference.len() as u64;
GenomicInterval {
chrom: record.chrom,
start,
end,
}
}
}
impl From<&crate::formats::bam::BamRecord> for GenomicInterval {
fn from(record: &crate::formats::bam::BamRecord) -> Self {
let start = if record.pos >= 0 {
record.pos as u64
} else {
0
};
let mut length: u64 = 0;
for op in &record.cigar {
use crate::formats::bam::CigarOp;
match op {
CigarOp::Match(len) | CigarOp::Del(len) | CigarOp::RefSkip(len)
| CigarOp::Equal(len) | CigarOp::Diff(len) => {
length += *len as u64;
}
_ => {} }
}
GenomicInterval {
chrom: record.rname.clone(),
start,
end: start + length,
}
}
}
impl From<crate::formats::bam::BamRecord> for GenomicInterval {
fn from(record: crate::formats::bam::BamRecord) -> Self {
(&record).into()
}
}
impl From<&crate::formats::sam::SamRecord> for GenomicInterval {
fn from(record: &crate::formats::sam::SamRecord) -> Self {
let start = if record.pos > 0 {
(record.pos - 1) as u64
} else {
0 };
let mut length: u64 = 0;
for op in &record.cigar {
use crate::formats::bam::CigarOp;
match op {
CigarOp::Match(len) | CigarOp::Del(len) | CigarOp::RefSkip(len)
| CigarOp::Equal(len) | CigarOp::Diff(len) => {
length += *len as u64;
}
_ => {}
}
}
GenomicInterval {
chrom: record.rname.clone(),
start,
end: start + length,
}
}
}
impl From<crate::formats::sam::SamRecord> for GenomicInterval {
fn from(record: crate::formats::sam::SamRecord) -> Self {
let start = if record.pos > 0 {
(record.pos - 1) as u64
} else {
0
};
let mut length: u64 = 0;
for op in &record.cigar {
use crate::formats::bam::CigarOp;
match op {
CigarOp::Match(len) | CigarOp::Del(len) | CigarOp::RefSkip(len)
| CigarOp::Equal(len) | CigarOp::Diff(len) => {
length += *len as u64;
}
_ => {}
}
}
GenomicInterval {
chrom: record.rname,
start,
end: start + length,
}
}
}
impl From<&crate::formats::gff::GffRecord> for GenomicInterval {
fn from(record: &crate::formats::gff::GffRecord) -> Self {
let start = if record.start > 0 {
record.start - 1
} else {
0
};
GenomicInterval {
chrom: record.seqid.clone(),
start,
end: record.end, }
}
}
impl From<crate::formats::gff::GffRecord> for GenomicInterval {
fn from(record: crate::formats::gff::GffRecord) -> Self {
let start = if record.start > 0 {
record.start - 1
} else {
0
};
GenomicInterval {
chrom: record.seqid,
start,
end: record.end,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::formats::bed::BedRecord;
#[test]
fn test_bed_conversion() {
let bed = BedRecord {
chrom: "chr1".to_string(),
start: 100,
end: 200,
name: None,
score: None,
strand: None,
thick_start: None,
thick_end: None,
item_rgb: None,
block_count: None,
block_sizes: None,
block_starts: None,
};
let interval: GenomicInterval = (&bed).into();
assert_eq!(interval.chrom, "chr1");
assert_eq!(interval.start, 100);
assert_eq!(interval.end, 200);
}
}