use std::{fmt::Debug, ops::ControlFlow};
use crate::collector::{Collector, CollectorBase, assert_collector};
use super::{Min, value_key::ValueKey};
#[derive(Clone)]
pub struct MinByKey<T, K, F> {
value_key_collector: Min<ValueKey<T, K>>,
f: F,
}
impl<T, K, F> MinByKey<T, K, F>
where
K: Ord,
F: FnMut(&T) -> K,
{
#[deprecated(since = "0.3.0", note = "Use `Min::by_key`")]
#[inline]
pub const fn new(f: F) -> Self {
assert_collector(Self {
value_key_collector: Min::new(),
f,
})
}
}
impl<T, K, F> CollectorBase for MinByKey<T, K, F> {
type Output = Option<T>;
#[inline]
fn finish(self) -> Self::Output {
self.value_key_collector.finish().map(ValueKey::into_value)
}
}
impl<T, K, F> Collector<T> for MinByKey<T, K, F>
where
K: Ord,
F: FnMut(&T) -> K,
{
#[inline]
fn collect(&mut self, item: T) -> ControlFlow<()> {
let item_value_key = ValueKey::new(item, &mut self.f);
self.value_key_collector.collect(item_value_key)
}
fn collect_many(&mut self, items: impl IntoIterator<Item = T>) -> ControlFlow<()> {
self.value_key_collector.collect_many(
items
.into_iter()
.map(|item| ValueKey::new(item, &mut self.f)),
)
}
fn collect_then_finish(self, items: impl IntoIterator<Item = T>) -> Self::Output {
let Self {
value_key_collector,
mut f,
} = self;
value_key_collector
.collect_then_finish(
items
.into_iter()
.map(move |item| ValueKey::new(item, &mut f)),
)
.map(ValueKey::into_value)
}
}
impl<T: Debug, K: Debug, F> Debug for MinByKey<T, K, F> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MinByKey")
.field("min_value_key", &self.value_key_collector.min)
.finish()
}
}