Skip to content

Commit

Permalink
gff/record: Parse score
Browse files Browse the repository at this point in the history
  • Loading branch information
zaeleus committed Nov 20, 2024
1 parent 8dca4da commit 0a5edd3
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 12 deletions.
3 changes: 2 additions & 1 deletion noodles-gff/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@

This splits the line into its key-optional value components.

* gff/record: Parse phase (`Record::phase`).
* gff/record: Parse score (`Record::score`) and phase
(`Record::phase`).

### Removed

Expand Down
31 changes: 27 additions & 4 deletions noodles-gff/src/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub use self::attributes::Attributes;
use self::fields::Fields;
use crate::record_buf::{Phase, Strand};

const MISSING: &str = ".";

/// An immutable, lazily-evalulated GFF record.
#[derive(Clone, Eq, PartialEq)]
pub struct Record<'l>(Fields<'l>);
Expand Down Expand Up @@ -47,8 +49,8 @@ impl<'l> Record<'l> {
}

/// Returns the score.
pub fn score(&self) -> &str {
self.0.score()
pub fn score(&self) -> Option<io::Result<f32>> {
parse_score(self.0.score())
}

/// Returns the strand.
Expand Down Expand Up @@ -83,14 +85,22 @@ impl<'l> fmt::Debug for Record<'l> {
}
}

fn parse_score(s: &str) -> Option<io::Result<f32>> {
match s {
MISSING => None,
_ => Some(
s.parse()
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)),
),
}
}

fn parse_strand(s: &str) -> io::Result<Strand> {
s.parse()
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
}

fn parse_phase(s: &str) -> Option<io::Result<Phase>> {
const MISSING: &str = ".";

match s {
MISSING => None,
_ => Some(
Expand All @@ -104,6 +114,19 @@ fn parse_phase(s: &str) -> Option<io::Result<Phase>> {
mod tests {
use super::*;

#[test]
fn test_parse_score() -> io::Result<()> {
assert!(parse_score(".").is_none());
assert_eq!(parse_score("0.0").transpose()?, Some(0.0));

assert!(matches!(
parse_phase(""),
Some(Err(e)) if e.kind() == io::ErrorKind::InvalidData
));

Ok(())
}

#[test]
fn test_parse_phase() -> io::Result<()> {
assert!(parse_phase(".").is_none());
Expand Down
9 changes: 2 additions & 7 deletions noodles-gff/src/record_buf/convert.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::io;

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

impl<'l> TryFrom<Record<'l>> for RecordBuf {
Expand All @@ -16,12 +16,7 @@ impl<'l> TryFrom<Record<'l>> for RecordBuf {
.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))?;

if let Some(score) = record.score().transpose()? {
builder = builder.set_score(score);
}

Expand Down

0 comments on commit 0a5edd3

Please sign in to comment.