Skip to content

Commit

Permalink
gff/record_buf: Add conversion from line::Record
Browse files Browse the repository at this point in the history
  • Loading branch information
zaeleus committed Nov 19, 2024
1 parent 7e6f4fa commit 59d83ce
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
1 change: 1 addition & 0 deletions noodles-gff/src/record_buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pub mod attributes;
mod builder;
mod convert;
mod field;
mod phase;
pub mod strand;
Expand Down
95 changes: 95 additions & 0 deletions noodles-gff/src/record_buf/convert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use std::io;

use super::{attributes::field::Value, RecordBuf, MISSING_FIELD};
use crate::{record::attributes::field::Value as ValueRef, Record};

impl<'l> TryFrom<Record<'l>> for RecordBuf {
type Error = io::Error;

fn try_from(record: Record<'l>) -> Result<Self, Self::Error> {
let mut builder = Self::builder();

builder = builder
.set_reference_sequence_name(record.reference_sequence_name().into())
.set_source(record.source().into())
.set_type(record.ty().into())
.set_start(record.start()?)
.set_end(record.end()?);

if record.score() != MISSING_FIELD {
let score = record
.score()
.parse()
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;

builder = builder.set_score(score);
}

builder = builder.set_strand(record.strand()?);

if record.phase() != MISSING_FIELD {
let phase = record
.phase()
.parse()
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;

builder = builder.set_phase(phase);
}

let attributes = record
.attributes()
.iter()
.map(|result| {
result.map(|(k, v)| {
let value = match v {
ValueRef::String(s) => Value::from(s),
ValueRef::Array(values) => {
Value::Array(values.iter().map(String::from).collect())
}
};

(k.into(), value)
})
})
.collect::<io::Result<_>>()?;

builder = builder.set_attributes(attributes);

Ok(builder.build())
}
}

#[cfg(test)]
mod tests {
use noodles_core::Position;

use super::*;
use crate::record_buf::Strand;

#[test]
fn test_try_from_record_for_record_buf() -> Result<(), Box<dyn std::error::Error>> {
let record = Record::try_new("sq0\t.\texon\t8\t13\t.\t+\t.\tID=0;Name=n0")?;
let actual = RecordBuf::try_from(record)?;

let expected = RecordBuf::builder()
.set_reference_sequence_name(String::from("sq0"))
.set_source(String::from("."))
.set_type(String::from("exon"))
.set_start(Position::try_from(8)?)
.set_end(Position::try_from(13)?)
.set_strand(Strand::Forward)
.set_attributes(
[
(String::from("ID"), Value::from("0")),
(String::from("Name"), Value::from("n0")),
]
.into_iter()
.collect(),
)
.build();

assert_eq!(actual, expected);

Ok(())
}
}

0 comments on commit 59d83ce

Please sign in to comment.