brrrr_lib/
types.rs

1// (c) Copyright 2022 Trent Hauck
2// All Rights Reserved
3
4use noodles::fasta;
5use noodles::fastq;
6use noodles::gff;
7use serde::Deserialize;
8use serde::Serialize;
9use std::collections::HashMap;
10use std::str;
11
12#[derive(Default, Clone, Debug, Serialize, Deserialize)]
13pub struct FastaRecord {
14    pub id: String,
15    pub desc: Option<String>,
16    pub seq: String,
17}
18
19impl From<fasta::Record> for FastaRecord {
20    fn from(src: fasta::Record) -> FastaRecord {
21        let seq = src.sequence();
22
23        let ss = str::from_utf8(&seq.as_ref()).unwrap();
24
25        FastaRecord {
26            id: src.name().to_string(),
27            desc: src.description().map_or(None, |i| Some(i.to_string())),
28            seq: String::from(ss),
29        }
30    }
31}
32
33#[derive(Default, Clone, Debug, Serialize, Deserialize)]
34pub struct FastqRecord {
35    pub id: String,
36    pub desc: Option<String>,
37    pub seq: String,
38    pub quality: String,
39}
40
41impl From<fastq::Record> for FastqRecord {
42    fn from(src: fastq::Record) -> FastqRecord {
43        let seq = src.sequence();
44
45        let ss = str::from_utf8(&seq.as_ref()).unwrap();
46
47        let noodles_quality = str::from_utf8(src.quality_scores()).unwrap();
48        let name = str::from_utf8(src.name()).unwrap();
49
50        FastqRecord {
51            id: String::from(name),
52            desc: None,
53            seq: String::from(ss),
54            quality: String::from(noodles_quality),
55        }
56    }
57}
58
59#[derive(Default, Clone, Debug, Serialize, Deserialize)]
60pub struct GffRecord {
61    pub seqname: String,
62    pub source: String,
63    pub feature_type: String,
64    pub start: usize,
65    pub end: usize,
66    pub score: Option<f32>,
67    pub strand: String,
68    pub frame: Option<String>,
69    pub attributes: HashMap<String, String>,
70}
71
72impl From<gff::Record> for GffRecord {
73    fn from(src: gff::Record) -> GffRecord {
74        let seqname = src.reference_sequence_name();
75        let source = src.source();
76        let feature_type = src.ty();
77        let start = src.start();
78        let end = src.end();
79        let score = src.score();
80        let strand = src.strand();
81        let phase = src.phase().map_or(None, |f| Some(f.to_string()));
82
83        let mut gff_attrs = HashMap::<String, String>::new();
84
85        for i in src.attributes().iter() {
86            let k = String::from(i.key());
87            let v = String::from(i.value());
88
89            // TODO: this isn't faithful to GFF3, value should be a vector
90            if gff_attrs.contains_key(&k) {
91                continue;
92            } else {
93                gff_attrs.insert(k, v);
94            }
95        }
96
97        GffRecord {
98            seqname: String::from(seqname),
99            source: String::from(source),
100            feature_type: String::from(feature_type),
101            start: usize::from(start),
102            end: usize::from(end),
103            score,
104            strand: String::from(strand.as_ref()),
105            frame: phase,
106            attributes: gff_attrs,
107        }
108    }
109}