Skip to main content

biomics/
lib.rs

1//! Early-stage bioinformatics primitives for Biomics.
2
3/// Calculate the fraction of DNA bases that are G or C.
4///
5/// ASCII case is ignored. Non-ACGT characters are excluded from the
6/// denominator.
7///
8/// # Examples
9///
10/// ```
11/// assert_eq!(biomics::gc_fraction(b"ACGT"), Some(0.5));
12/// ```
13#[must_use]
14pub fn gc_fraction(sequence: &[u8]) -> Option<f64> {
15    let mut valid = 0usize;
16    let mut gc = 0usize;
17
18    for base in sequence {
19        match base.to_ascii_uppercase() {
20            b'G' | b'C' => {
21                valid += 1;
22                gc += 1;
23            }
24            b'A' | b'T' => valid += 1,
25            _ => {}
26        }
27    }
28
29    (valid != 0).then(|| gc as f64 / valid as f64)
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn calculates_gc_fraction() {
38        assert_eq!(gc_fraction(b"ACGT"), Some(0.5));
39        assert_eq!(gc_fraction(b"GGCC"), Some(1.0));
40    }
41
42    #[test]
43    fn ignores_unknown_characters() {
44        assert_eq!(gc_fraction(b"GCNN"), Some(1.0));
45    }
46
47    #[test]
48    fn handles_empty_sequences() {
49        assert_eq!(gc_fraction(b""), None);
50    }
51}