From dd0669192344bf8e7423829adfc9fd6219701d69 Mon Sep 17 00:00:00 2001 From: Steve Wooster Date: Thu, 1 Dec 2022 12:16:37 -0800 Subject: [PATCH] Switch extension trait from IntoIterators to Interators --- benches/all_windows.rs | 8 ++-- src/iter.rs | 91 +++++++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 50 deletions(-) diff --git a/benches/all_windows.rs b/benches/all_windows.rs index 3623bcb..c09d582 100644 --- a/benches/all_windows.rs +++ b/benches/all_windows.rs @@ -3,7 +3,7 @@ use rand::{rngs::OsRng, seq::SliceRandom}; use smallvec::SmallVec; use quickdna::{ - BaseSequence, DnaSequence, Nucleotide, NucleotideLike, Nucleotides, TranslationTable, + BaseSequence, DnaSequence, Nucleotide, NucleotideLike, NucleotideIter, TranslationTable, }; static PROTEIN_WINDOW_LEN: usize = 20; @@ -111,12 +111,12 @@ impl IterBasedSequenceWindows { fn from_dna(dna: &[Nucleotide], dna_window_len: usize, protein_window_len: usize) -> Self { let mut aas = SmallVec::new(); let ncbi1 = TranslationTable::Ncbi1.to_fn(); - aas.extend(dna.self_reading_frames().into_iter().map(|codons| { + aas.extend(dna.iter().self_reading_frames().into_iter().map(|codons| { let translated: Vec<_> = codons.map(ncbi1).collect(); String::from_utf8(translated).unwrap() })); aas.extend( - dna.reverse_complement() + dna.iter().reverse_complement() .self_reading_frames() .into_iter() .map(|codons| { @@ -125,7 +125,7 @@ impl IterBasedSequenceWindows { }), ); - let dna_rc = (&dna).reverse_complement().map(|n| n.to_ascii()).collect(); + let dna_rc = dna.iter().reverse_complement().map(|n| n.to_ascii()).collect(); let dna_rc = String::from_utf8(dna_rc).unwrap(); let dna = dna.iter().map(|n| n.to_ascii()).collect(); diff --git a/src/iter.rs b/src/iter.rs index f4ae6eb..c9442fd 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -46,8 +46,8 @@ impl ToNucleotideLike for &NucleotideAmbiguous { } } -/// Extension trait for nucleotide sequences -pub trait Nucleotides: IntoIterator { +/// Extension trait for nucleotide iterators +pub trait NucleotideIter: Iterator + Sized { /// Returns up to 6 non-empty codon iterators for forward and reverse complement reading frames. /// /// The foward codon iterators are given before the reverse complement ones, with the forward @@ -58,12 +58,12 @@ pub trait Nucleotides: IntoIterator { /// # Examples /// /// ``` - /// use quickdna::{Nucleotide, Nucleotides}; + /// use quickdna::{Nucleotide, NucleotideIter}; /// /// use Nucleotide::*; /// let dna = [C, G, A, T, C, G, A, T]; /// - /// let frames = dna.all_reading_frames(); + /// let frames = dna.iter().all_reading_frames(); /// assert_eq!(frames.len(), 6); /// assert!(frames[0].clone().eq([ /// [C, G, A].into(), @@ -92,7 +92,7 @@ pub trait Nucleotides: IntoIterator { /// /// // The last forward and RC reading frames are omitted /// // because they would only have 2 nucleotides. - /// let frames = dna[..4].all_reading_frames(); + /// let frames = dna[..4].iter().all_reading_frames(); /// assert_eq!(frames.len(), 4); /// assert!(frames[0].clone().eq([ /// [C, G, A].into(), @@ -108,12 +108,12 @@ pub trait Nucleotides: IntoIterator { /// ])); /// /// // All reading frames are omitted due to insufficient nucleotides. - /// let frames = dna[..2].all_reading_frames(); + /// let frames = dna[..2].iter().all_reading_frames(); /// assert!(frames.is_empty()); /// ``` - fn all_reading_frames(self) -> SmallVec<[ForwardOrRcCodons; 6]> + fn all_reading_frames(self) -> SmallVec<[ForwardOrRcCodons; 6]> where - Self::IntoIter: Clone + DoubleEndedIterator + ExactSizeIterator; + Self: Clone + DoubleEndedIterator + ExactSizeIterator; /// Returns iterator of codons for the first reading frame of this nucleotide sequence. /// If the number of nucleotides isn't divisible by 3, excess nucleotides are silently @@ -123,7 +123,7 @@ pub trait Nucleotides: IntoIterator { /// # Examples /// /// ``` - /// use quickdna::{Codons, Nucleotide, Nucleotides}; + /// use quickdna::{Codons, Nucleotide, NucleotideIter}; /// /// use Nucleotide::*; /// let dna = [C, G, A, T, C, G, A, T]; @@ -132,41 +132,41 @@ pub trait Nucleotides: IntoIterator { /// [C, G, A].into(), /// [T, C, G].into(), /// ]; - /// assert!(dna.codons().eq(expected_codons)); + /// assert!(dna.iter().codons().eq(expected_codons)); /// - /// assert!(dna.codons().eq(dna.self_reading_frames().remove(0))); + /// assert!(dna.iter().codons().eq(dna.iter().self_reading_frames().remove(0))); /// ``` - fn codons(self) -> Codons; + fn codons(self) -> Codons; /// Returns iterator of complementary nucleotides. /// /// # Examples /// /// ``` - /// use quickdna::{Nucleotide, Nucleotides}; + /// use quickdna::{Nucleotide, NucleotideIter}; /// /// use Nucleotide::*; /// let dna = [C, G, A, T]; /// - /// assert!(dna.complement().eq([G, C, T, A])); + /// assert!(dna.iter().complement().eq([G, C, T, A])); /// ``` - fn complement(self) -> Complement; + fn complement(self) -> Complement; /// Returns iterator of reverse complement of contained nucleotides. /// /// # Examples /// /// ``` - /// use quickdna::{Nucleotide, Nucleotides}; + /// use quickdna::{Nucleotide, NucleotideIter}; /// /// use Nucleotide::*; /// let dna = [C, G, A, T]; /// - /// assert!(dna.reverse_complement().eq([A, T, C, G])); + /// assert!(dna.iter().reverse_complement().eq([A, T, C, G])); /// ``` - fn reverse_complement(self) -> std::iter::Rev> + fn reverse_complement(self) -> std::iter::Rev> where - Self::IntoIter: DoubleEndedIterator; + Self: DoubleEndedIterator; /// Returns up to 3 non-empty codon iterators for reading frames. /// @@ -176,12 +176,12 @@ pub trait Nucleotides: IntoIterator { /// # Examples /// /// ``` - /// use quickdna::{Nucleotide, Nucleotides}; + /// use quickdna::{Nucleotide, NucleotideIter}; /// /// use Nucleotide::*; /// let dna = [C, G, A, T, C, G, A, T]; /// - /// let frames = dna.self_reading_frames(); + /// let frames = dna.iter().self_reading_frames(); /// assert_eq!(frames.len(), 3); /// assert!(frames[0].clone().eq([ /// [C, G, A].into(), @@ -197,7 +197,7 @@ pub trait Nucleotides: IntoIterator { /// ])); /// /// // The last reading frame is omitted because it would only have 2 nucleotides. - /// let frames = dna[..4].self_reading_frames(); + /// let frames = dna[..4].iter().self_reading_frames(); /// assert_eq!(frames.len(), 2); /// assert!(frames[0].clone().eq([ /// [C, G, A].into(), @@ -207,25 +207,24 @@ pub trait Nucleotides: IntoIterator { /// ])); /// /// // All reading frames are omitted due to insufficient nucleotides. - /// let frames = dna[..2].self_reading_frames(); + /// let frames = dna[..2].iter().self_reading_frames(); /// assert!(frames.is_empty()); /// ``` - fn self_reading_frames(self) -> SmallVec<[Codons; 3]> + fn self_reading_frames(self) -> SmallVec<[Codons; 3]> where - Self::IntoIter: Clone + ExactSizeIterator; + Self: Clone + ExactSizeIterator; } -impl Nucleotides for T +impl NucleotideIter for I where N: ToNucleotideLike, I: Iterator, - T: IntoIterator, { - fn all_reading_frames(self) -> SmallVec<[ForwardOrRcCodons; 6]> + fn all_reading_frames(self) -> SmallVec<[ForwardOrRcCodons; 6]> where - Self::IntoIter: Clone + DoubleEndedIterator + ExactSizeIterator, + Self: Clone + DoubleEndedIterator + ExactSizeIterator, { - let iter1 = self.into_iter(); + let iter1 = self; let mut iter2 = iter1.clone(); iter2.next(); let mut iter3 = iter2.clone(); @@ -249,26 +248,26 @@ where frames } - fn codons(self) -> Codons { - Codons(self.into_iter()) + fn codons(self) -> Codons { + Codons(self) } - fn complement(self) -> Complement { - Complement(self.into_iter()) + fn complement(self) -> Complement { + Complement(self) } - fn reverse_complement(self) -> std::iter::Rev> + fn reverse_complement(self) -> std::iter::Rev> where - Self::IntoIter: DoubleEndedIterator, + Self: DoubleEndedIterator, { self.complement().rev() } - fn self_reading_frames(self) -> SmallVec<[Codons; 3]> + fn self_reading_frames(self) -> SmallVec<[Codons; 3]> where - Self::IntoIter: Clone + ExactSizeIterator, + Self: Clone + ExactSizeIterator, { - let iter1 = self.into_iter(); + let iter1 = self; let mut iter2 = iter1.clone(); iter2.next(); let mut iter3 = iter2.clone(); @@ -281,8 +280,8 @@ where /// Adapter yielding codons of the contained iterator. /// -/// This `struct` is created by the [`codons`](Nucleotides::codons) -/// method on [`Nucleotides`]. See its documentation for more. +/// This `struct` is created by the [`codons`](NucleotideIter::codons) +/// method on [`NucleotideIter`]. See its documentation for more. #[derive(Clone, Debug)] pub struct Codons(I); @@ -339,8 +338,8 @@ where /// Adapter yielding complementary nucleotide of the contained iterator. /// -/// This `struct` is created by the [`complement`](Nucleotides::complement) -/// method on [`Nucleotides`]. See its documentation for more. +/// This `struct` is created by the [`complement`](NucleotideIter::complement) +/// method on [`NucleotideIter`]. See its documentation for more. #[derive(Clone, Debug)] pub struct Complement(I); @@ -384,8 +383,8 @@ where /// Adapter capable of holding either forward codon iterators or reverse complement codon iterators. /// -/// This `struct` is created by the [`all_reading_frames`](Nucleotides::all_reading_frames) -/// method on [`Nucleotides`]. See its documentation for more. +/// This `struct` is created by the [`all_reading_frames`](NucleotideIter::all_reading_frames) +/// method on [`NucleotideIter`]. See its documentation for more. #[derive(Clone, Debug)] pub enum ForwardOrRcCodons { Forward(Codons), @@ -449,7 +448,7 @@ mod test { fn test_reverse_codons() { use Nucleotide::*; let dna = [A, A, T, T, C, C, G, G]; - let rev_codons: Vec<_> = dna.codons().rev().collect(); + let rev_codons: Vec<_> = dna.iter().codons().rev().collect(); let expected = [[T, C, C].into(), [A, A, T].into()]; assert_eq!(rev_codons, expected); }