Skip to content

Commit 87f2011

Browse files
authored
fix: bam::Record:new should return a valid record (#361)
* bam::Record:new should return a valid record, see #339
1 parent 56ee2bd commit 87f2011

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

src/bam/mod.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2451,7 +2451,7 @@ CCCCCCCCCCCCCCCCCCC"[..],
24512451
where
24522452
F: Fn(&record::Record) -> Option<bool>,
24532453
{
2454-
let mut bam_reader = Reader::from_path(bamfile).unwrap(); // internal functions, just unwarp
2454+
let mut bam_reader = Reader::from_path(bamfile).unwrap(); // internal functions, just unwrap
24552455
let header = header::Header::from_template(bam_reader.header());
24562456
let mut sam_writer = Writer::from_path(samfile, &header, Format::Sam).unwrap();
24572457
for record in bam_reader.records() {
@@ -3002,6 +3002,58 @@ CCCCCCCCCCCCCCCCCCC"[..],
30023002
assert_eq!(header_refseqs[0].get("LN").unwrap(), "10000000",);
30033003
}
30043004

3005+
#[test]
3006+
fn test_bam_new() {
3007+
// Create the path to write the tmp test BAM
3008+
let tmp = tempfile::Builder::new()
3009+
.prefix("rust-htslib")
3010+
.tempdir()
3011+
.expect("Cannot create temp dir");
3012+
let bampath = tmp.path().join("test.bam");
3013+
3014+
// write an unmapped BAM record (uBAM)
3015+
{
3016+
// Build the header
3017+
let mut header = Header::new();
3018+
3019+
// Add the version
3020+
header.push_record(
3021+
HeaderRecord::new(b"HD")
3022+
.push_tag(b"VN", &"1.6")
3023+
.push_tag(b"SO", &"unsorted"),
3024+
);
3025+
3026+
// Build the writer
3027+
let mut writer = Writer::from_path(&bampath, &header, Format::Bam).unwrap();
3028+
3029+
// Build an empty record
3030+
let mut record = Record::new();
3031+
3032+
// Write the record (this previously seg-faulted)
3033+
assert!(writer.write(&record).is_ok());
3034+
}
3035+
3036+
// Read the record
3037+
{
3038+
// Build th reader
3039+
let mut reader = Reader::from_path(&bampath).expect("Error opening file.");
3040+
3041+
// Read the record
3042+
let mut rec = Record::new();
3043+
match reader.read(&mut rec) {
3044+
Some(r) => r.expect("Failed to read record."),
3045+
None => panic!("No record read."),
3046+
};
3047+
3048+
// Check a few things
3049+
assert!(rec.is_unmapped());
3050+
assert_eq!(rec.tid(), -1);
3051+
assert_eq!(rec.pos(), -1);
3052+
assert_eq!(rec.mtid(), -1);
3053+
assert_eq!(rec.mpos(), -1);
3054+
}
3055+
}
3056+
30053057
#[test]
30063058
fn test_idxstats_bam() {
30073059
let mut reader = IndexedReader::from_path("test/test.bam").unwrap();

src/bam/record.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,23 @@ fn extranul_from_qname(qname: &[u8]) -> usize {
114114
impl Record {
115115
/// Create an empty BAM record.
116116
pub fn new() -> Self {
117-
Record {
117+
let mut record = Record {
118118
inner: unsafe { MaybeUninit::zeroed().assume_init() },
119119
own: true,
120120
cigar: None,
121121
header: None,
122-
}
122+
};
123+
// The read/query name needs to be set as empty to properly initialize
124+
// the record
125+
record.set_qname(b"");
126+
// Developer note: these are needed so the returned record is properly
127+
// initialized as unmapped.
128+
record.set_unmapped();
129+
record.set_tid(-1);
130+
record.set_pos(-1);
131+
record.set_mpos(-1);
132+
record.set_mtid(-1);
133+
record
123134
}
124135

125136
pub fn from_inner(from: *mut htslib::bam1_t) -> Self {

src/bam/record_serde.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use serde_bytes::{ByteBuf, Bytes};
88
use crate::bam::record::Record;
99

1010
fn fix_l_extranul(rec: &mut Record) {
11+
// first, reset the number of extranuls to 0 for calling .qname(); then calculate how many we actually have
12+
rec.inner_mut().core.l_extranul = 0;
1113
let l_extranul = rec.qname().iter().rev().take_while(|x| **x == 0u8).count() as u8;
1214
rec.inner_mut().core.l_extranul = l_extranul;
1315
}

0 commit comments

Comments
 (0)