diff --git a/noodles-gff/CHANGELOG.md b/noodles-gff/CHANGELOG.md index 095af7d5a..5381fbfd1 100644 --- a/noodles-gff/CHANGELOG.md +++ b/noodles-gff/CHANGELOG.md @@ -36,6 +36,8 @@ This splits the line into its key-optional value components. + * gff/record: Parse phase (`Record::phase`). + ### Removed * gff: Remove `lazy` module. diff --git a/noodles-gff/src/record.rs b/noodles-gff/src/record.rs index 5174f9616..87246f54d 100644 --- a/noodles-gff/src/record.rs +++ b/noodles-gff/src/record.rs @@ -10,7 +10,7 @@ use noodles_core::Position; pub use self::attributes::Attributes; use self::fields::Fields; -use crate::record_buf::Strand; +use crate::record_buf::{Phase, Strand}; /// An immutable, lazily-evalulated GFF record. #[derive(Clone, Eq, PartialEq)] @@ -57,8 +57,8 @@ impl<'l> Record<'l> { } /// Returns the phase. - pub fn phase(&self) -> &str { - self.0.phase() + pub fn phase(&self) -> Option> { + parse_phase(self.0.phase()) } /// Returns the attributes. @@ -87,3 +87,35 @@ fn parse_strand(s: &str) -> io::Result { s.parse() .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) } + +fn parse_phase(s: &str) -> Option> { + const MISSING: &str = "."; + + match s { + MISSING => None, + _ => Some( + s.parse() + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)), + ), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_phase() -> io::Result<()> { + assert!(parse_phase(".").is_none()); + assert_eq!(parse_phase("0").transpose()?, Some(Phase::Zero)); + assert_eq!(parse_phase("1").transpose()?, Some(Phase::One)); + assert_eq!(parse_phase("2").transpose()?, Some(Phase::Two)); + + assert!(matches!( + parse_phase(""), + Some(Err(e)) if e.kind() == io::ErrorKind::InvalidData + )); + + Ok(()) + } +} diff --git a/noodles-gff/src/record_buf/convert.rs b/noodles-gff/src/record_buf/convert.rs index 21805f092..5ea1cee2d 100644 --- a/noodles-gff/src/record_buf/convert.rs +++ b/noodles-gff/src/record_buf/convert.rs @@ -27,12 +27,7 @@ impl<'l> TryFrom> for RecordBuf { 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))?; - + if let Some(phase) = record.phase().transpose()? { builder = builder.set_phase(phase); }