Skip to main content

homopolymer_compress/
lib.rs

1//! Functions to homopolymer compress arbitrary sequences.
2
3#![warn(missing_docs)]
4
5/// Homopolymer compress the given sequence.
6pub fn homopolymer_compress<
7    'output,
8    Input: 'output + IntoIterator<Item = Item>,
9    Item: 'output + Eq + Clone,
10>(
11    input: Input,
12) -> impl 'output + Iterator<Item = Item> {
13    input
14        .into_iter()
15        .scan(None, |previous_item, item| {
16            if let Some(previous_item) = previous_item.as_mut() {
17                if *previous_item == item {
18                    Some(None)
19                } else {
20                    *previous_item = item.clone();
21                    Some(Some(item))
22                }
23            } else {
24                *previous_item = Some(item.clone());
25                Some(Some(item))
26            }
27        })
28        .flatten()
29}
30
31#[cfg(test)]
32mod tests {
33    use crate::homopolymer_compress;
34
35    #[test]
36    fn test_homopolymer_compression() {
37        let input = b"ACAARRRTGGGTGTJASAAAI";
38        let expected = Vec::from_iter(b"ACARTGTGTJASAI".iter().cloned());
39        let actual = Vec::from_iter(homopolymer_compress(input.iter().cloned()));
40        assert_eq!(expected, actual);
41    }
42}