Skip to main content

gxfkit_core/
model.rs

1//! The in-memory record model.
2
3use crate::attributes::Attributes;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum Strand {
7    Forward,
8    Reverse,
9    Unstranded, // '.'
10    Unknown,    // '?'
11}
12
13impl Strand {
14    pub fn parse(s: &str) -> Strand {
15        match s {
16            "+" => Strand::Forward,
17            "-" => Strand::Reverse,
18            "?" => Strand::Unknown,
19            _ => Strand::Unstranded,
20        }
21    }
22
23    pub fn as_str(&self) -> &'static str {
24        match self {
25            Strand::Forward => "+",
26            Strand::Reverse => "-",
27            Strand::Unstranded => ".",
28            Strand::Unknown => "?",
29        }
30    }
31}
32
33/// A single GFF/GTF feature line.
34///
35/// `score` and `phase` are kept as raw strings rather than parsed numbers so we
36/// never lose or reformat the original token (important for byte-parity).
37#[derive(Debug, Clone)]
38pub struct Record {
39    pub seqid: String,
40    pub source: String,
41    pub feature_type: String,
42    pub start: u64,
43    pub end: u64,
44    pub score: String,
45    pub strand: Strand,
46    pub phase: String,
47    pub attributes: Attributes,
48}
49
50impl Record {
51    pub fn id(&self) -> Option<&str> {
52        self.attributes.get("ID")
53    }
54
55    /// First parent (GFF3 permits multiple, comma-separated).
56    pub fn parent(&self) -> Option<&str> {
57        self.attributes.first("Parent")
58    }
59}