diff --git a/src/collection/album.rs b/src/collection/album.rs index 40da9a1..5163eb6 100644 --- a/src/collection/album.rs +++ b/src/collection/album.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use super::track::Track; // FIXME: check direction of import. -use super::{Merge, MergeSorted}; +use super::merge::{Merge, MergeSorted}; /// The album identifier. #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Ord, Eq, Hash)] diff --git a/src/collection/artist.rs b/src/collection/artist.rs index 2d99592..639577a 100644 --- a/src/collection/artist.rs +++ b/src/collection/artist.rs @@ -11,7 +11,7 @@ use uuid::Uuid; use super::album::Album; // FIXME: check direction of import. -use super::{Merge, MergeSorted}; +use super::merge::{Merge, MergeSorted}; // FIXME: these imports are not acceptable use crate::Error; diff --git a/src/collection/merge.rs b/src/collection/merge.rs new file mode 100644 index 0000000..8c7a9a4 --- /dev/null +++ b/src/collection/merge.rs @@ -0,0 +1,65 @@ +use std::{cmp::Ordering, iter::Peekable}; + +pub trait Merge { + fn merge_in_place(&mut self, other: Self); + + fn merge(mut self, other: Self) -> Self + where + Self: Sized, + { + self.merge_in_place(other); + self + } + + fn merge_vecs(this: &mut Vec, mut other: Vec) { + this.append(&mut other); + this.sort_unstable(); + this.dedup(); + } +} + +pub struct MergeSorted +where + L: Iterator, + R: Iterator, +{ + left: Peekable, + right: Peekable, +} + +impl MergeSorted +where + L: Iterator, + R: Iterator, +{ + pub fn new(left: L, right: R) -> MergeSorted { + MergeSorted { + left: left.peekable(), + right: right.peekable(), + } + } +} + +impl Iterator for MergeSorted +where + L: Iterator, + R: Iterator, + L::Item: Ord + Merge, +{ + type Item = L::Item; + + fn next(&mut self) -> Option { + let which = match (self.left.peek(), self.right.peek()) { + (Some(l), Some(r)) => l.cmp(r), + (Some(_), None) => Ordering::Less, + (None, Some(_)) => Ordering::Greater, + (None, None) => return None, + }; + + match which { + Ordering::Less => self.left.next(), + Ordering::Equal => Some(self.left.next().unwrap().merge(self.right.next().unwrap())), + Ordering::Greater => self.right.next(), + } + } +} diff --git a/src/collection/mod.rs b/src/collection/mod.rs index b10883d..6f412b5 100644 --- a/src/collection/mod.rs +++ b/src/collection/mod.rs @@ -2,72 +2,8 @@ pub mod album; pub mod artist; pub mod track; -use std::{cmp::Ordering, iter::Peekable}; - -// FIXME: should not be public -pub trait Merge { - fn merge_in_place(&mut self, other: Self); - - fn merge(mut self, other: Self) -> Self - where - Self: Sized, - { - self.merge_in_place(other); - self - } - - fn merge_vecs(this: &mut Vec, mut other: Vec) { - this.append(&mut other); - this.sort_unstable(); - this.dedup(); - } -} - -struct MergeSorted -where - L: Iterator, - R: Iterator, -{ - left: Peekable, - right: Peekable, -} - -impl MergeSorted -where - L: Iterator, - R: Iterator, -{ - fn new(left: L, right: R) -> MergeSorted { - MergeSorted { - left: left.peekable(), - right: right.peekable(), - } - } -} - -impl Iterator for MergeSorted -where - L: Iterator, - R: Iterator, - L::Item: Ord + Merge, -{ - type Item = L::Item; - - fn next(&mut self) -> Option { - let which = match (self.left.peek(), self.right.peek()) { - (Some(l), Some(r)) => l.cmp(r), - (Some(_), None) => Ordering::Less, - (None, Some(_)) => Ordering::Greater, - (None, None) => return None, - }; - - match which { - Ordering::Less => self.left.next(), - Ordering::Equal => Some(self.left.next().unwrap().merge(self.right.next().unwrap())), - Ordering::Greater => self.right.next(), - } - } -} +mod merge; +pub use merge::Merge; /// The collection alias type for convenience. pub type Collection = Vec; diff --git a/src/collection/track.rs b/src/collection/track.rs index f4279fd..f0510c2 100644 --- a/src/collection/track.rs +++ b/src/collection/track.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; // FIXME: check direction of import. -use super::Merge; +use super::merge::Merge; /// The track file format. #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)]