use alloc::{string::String, vec::Vec};
use core::{fmt::Debug, hash::Hash};
use serde::{Serialize, de::DeserializeOwned};
use crate::{
corpus::CorpusId,
inputs::{Input, ListInput},
};
pub type MultipartInput<I, K> = ListInput<(K, I)>;
impl<I, K> Input for MultipartInput<I, K>
where
I: Input,
K: PartialEq + Debug + Serialize + DeserializeOwned + Clone + Hash,
{
fn generate_name(&self, id: Option<CorpusId>) -> String {
self.parts()
.iter()
.map(|(_k, i)| i.generate_name(id))
.collect::<Vec<_>>()
.join(",")
}
}
pub trait Keyed<K, V> {
fn keys<'a>(&'a self) -> impl Iterator<Item = &'a K>
where
K: 'a;
fn with_key<'a, 'b>(&'b self, key: &'a K) -> impl Iterator<Item = (usize, &'b V)> + 'a
where
'b: 'a,
V: 'b;
fn with_key_mut<'a, 'b>(
&'b mut self,
key: &'a K,
) -> impl Iterator<Item = (usize, &'b mut V)> + 'a
where
'b: 'a,
V: 'b;
}
impl<I, K> Keyed<K, I> for MultipartInput<I, K>
where
K: PartialEq,
{
fn keys<'a>(&'a self) -> impl Iterator<Item = &'a K>
where
K: 'a,
{
self.parts().iter().map(|(k, _)| k)
}
fn with_key<'a, 'b>(&'b self, key: &'a K) -> impl Iterator<Item = (usize, &'b I)> + 'a
where
'b: 'a,
I: 'b,
{
self.parts()
.iter()
.enumerate()
.filter_map(move |(i, (k, input))| (key == k).then_some((i, input)))
}
fn with_key_mut<'a, 'b>(
&'b mut self,
key: &'a K,
) -> impl Iterator<Item = (usize, &'b mut I)> + 'a
where
'b: 'a,
I: 'b,
{
self.parts_mut()
.iter_mut()
.enumerate()
.filter_map(move |(i, (k, input))| (key == k).then_some((i, input)))
}
}