1#[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}