Split out merge trait
This commit is contained in:
parent
7809ba4d67
commit
839193ce39
@ -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)]
|
||||
|
@ -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;
|
||||
|
65
src/collection/merge.rs
Normal file
65
src/collection/merge.rs
Normal file
@ -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<T: Ord + Eq>(this: &mut Vec<T>, mut other: Vec<T>) {
|
||||
this.append(&mut other);
|
||||
this.sort_unstable();
|
||||
this.dedup();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MergeSorted<L, R>
|
||||
where
|
||||
L: Iterator<Item = R::Item>,
|
||||
R: Iterator,
|
||||
{
|
||||
left: Peekable<L>,
|
||||
right: Peekable<R>,
|
||||
}
|
||||
|
||||
impl<L, R> MergeSorted<L, R>
|
||||
where
|
||||
L: Iterator<Item = R::Item>,
|
||||
R: Iterator,
|
||||
{
|
||||
pub fn new(left: L, right: R) -> MergeSorted<L, R> {
|
||||
MergeSorted {
|
||||
left: left.peekable(),
|
||||
right: right.peekable(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> Iterator for MergeSorted<L, R>
|
||||
where
|
||||
L: Iterator<Item = R::Item>,
|
||||
R: Iterator,
|
||||
L::Item: Ord + Merge,
|
||||
{
|
||||
type Item = L::Item;
|
||||
|
||||
fn next(&mut self) -> Option<L::Item> {
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
@ -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<T: Ord + Eq>(this: &mut Vec<T>, mut other: Vec<T>) {
|
||||
this.append(&mut other);
|
||||
this.sort_unstable();
|
||||
this.dedup();
|
||||
}
|
||||
}
|
||||
|
||||
struct MergeSorted<L, R>
|
||||
where
|
||||
L: Iterator<Item = R::Item>,
|
||||
R: Iterator,
|
||||
{
|
||||
left: Peekable<L>,
|
||||
right: Peekable<R>,
|
||||
}
|
||||
|
||||
impl<L, R> MergeSorted<L, R>
|
||||
where
|
||||
L: Iterator<Item = R::Item>,
|
||||
R: Iterator,
|
||||
{
|
||||
fn new(left: L, right: R) -> MergeSorted<L, R> {
|
||||
MergeSorted {
|
||||
left: left.peekable(),
|
||||
right: right.peekable(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<L, R> Iterator for MergeSorted<L, R>
|
||||
where
|
||||
L: Iterator<Item = R::Item>,
|
||||
R: Iterator,
|
||||
L::Item: Ord + Merge,
|
||||
{
|
||||
type Item = L::Item;
|
||||
|
||||
fn next(&mut self) -> Option<L::Item> {
|
||||
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<artist::Artist>;
|
||||
|
@ -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)]
|
||||
|
Loading…
Reference in New Issue
Block a user