pub fn reverse_complement(seq: &str) -> String {
seq.chars()
.rev()
.map(|c| match c {
'A' => 'T',
'T' => 'A',
'G' => 'C',
'C' => 'G',
'a' => 't',
't' => 'a',
'g' => 'c',
'c' => 'g',
_ => c,
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_reverse_complement_basic() {
assert_eq!(reverse_complement("ATGC"), "GCAT");
}
#[test]
fn test_reverse_complement_empty() {
assert_eq!(reverse_complement(""), "");
}
#[test]
fn test_reverse_complement_single_base() {
assert_eq!(reverse_complement("A"), "T");
assert_eq!(reverse_complement("T"), "A");
assert_eq!(reverse_complement("G"), "C");
assert_eq!(reverse_complement("C"), "G");
}
#[test]
fn test_reverse_complement_lowercase() {
assert_eq!(reverse_complement("atgc"), "gcat");
assert_eq!(reverse_complement("aattggcc"), "ggccaatt");
}
#[test]
fn test_reverse_complement_mixed_case() {
assert_eq!(reverse_complement("AtGc"), "gCaT");
assert_eq!(reverse_complement("AaTtGgCc"), "gGcCaAtT");
}
#[test]
fn test_reverse_complement_with_n() {
assert_eq!(reverse_complement("ATGN"), "NCAT");
assert_eq!(reverse_complement("NNNN"), "NNNN");
assert_eq!(reverse_complement("ANT"), "ANT");
}
#[test]
fn test_reverse_complement_preserves_unknown_chars() {
assert_eq!(reverse_complement("ATGXYZ"), "ZYXCAT");
assert_eq!(reverse_complement("A-T-G"), "C-A-T");
}
#[test]
fn test_reverse_complement_palindrome() {
assert_eq!(reverse_complement("ATAT"), "ATAT");
assert_eq!(reverse_complement("GCGC"), "GCGC");
}
#[test]
fn test_reverse_complement_long_sequence() {
let seq = "ATGCATGCATGCATGCATGCATGCATGCATGCATGCATGC";
let rc = reverse_complement(seq);
assert_eq!(reverse_complement(&rc), seq);
}
#[test]
fn test_reverse_complement_real_codon() {
assert_eq!(reverse_complement("ATG"), "CAT");
assert_eq!(reverse_complement("TAA"), "TTA");
assert_eq!(reverse_complement("TAG"), "CTA");
assert_eq!(reverse_complement("TGA"), "TCA");
}
}