Split out merge trait
All checks were successful
Cargo CI / Build and Test (pull_request) Successful in 1m2s
Cargo CI / Lint (pull_request) Successful in 44s

This commit is contained in:
Wojciech Kozlowski 2024-01-21 18:30:12 +01:00
parent 7809ba4d67
commit 839193ce39
5 changed files with 70 additions and 69 deletions

View File

@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use super::track::Track; use super::track::Track;
// FIXME: check direction of import. // FIXME: check direction of import.
use super::{Merge, MergeSorted}; use super::merge::{Merge, MergeSorted};
/// The album identifier. /// The album identifier.
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Ord, Eq, Hash)] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Ord, Eq, Hash)]

View File

@ -11,7 +11,7 @@ use uuid::Uuid;
use super::album::Album; use super::album::Album;
// FIXME: check direction of import. // FIXME: check direction of import.
use super::{Merge, MergeSorted}; use super::merge::{Merge, MergeSorted};
// FIXME: these imports are not acceptable // FIXME: these imports are not acceptable
use crate::Error; use crate::Error;

65
src/collection/merge.rs Normal file
View 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(),
}
}
}

View File

@ -2,72 +2,8 @@ pub mod album;
pub mod artist; pub mod artist;
pub mod track; pub mod track;
use std::{cmp::Ordering, iter::Peekable}; mod merge;
pub use merge::Merge;
// 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(),
}
}
}
/// The collection alias type for convenience. /// The collection alias type for convenience.
pub type Collection = Vec<artist::Artist>; pub type Collection = Vec<artist::Artist>;

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
// FIXME: check direction of import. // FIXME: check direction of import.
use super::Merge; use super::merge::Merge;
/// The track file format. /// The track file format.
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)]