pub trait Many<T> {
type Iter: Iterator<Item = T>;
fn iter_many(self) -> Self::Iter;
}
impl<T, I: Into<T>, const N: usize> Many<T> for [I; N] {
type Iter = std::iter::Map<std::array::IntoIter<I, N>, fn(I) -> T>;
fn iter_many(self) -> Self::Iter {
self.into_iter().map(Into::into)
}
}
impl<T, I: Into<T>> Many<T> for Vec<I> {
type Iter = std::iter::Map<std::vec::IntoIter<I>, fn(I) -> T>;
fn iter_many(self) -> Self::Iter {
self.into_iter().map(Into::into)
}
}
macro_rules! impl_single_insertable {
($(
impl$(<$($life:lifetime),+>)? $target:path,
)+) => {
$(
impl<$($($life,)+)? I: Into<$target>> Many<$target> for I {
type Iter = std::iter::Once<$target>;
fn iter_many(self) -> Self::Iter {
std::iter::once(self.into())
}
}
impl$(<$($life),+>)? Many<$target> for Option<$target> {
type Iter = std::option::IntoIter<$target>;
fn iter_many(self) -> Self::Iter {
self.into_iter()
}
}
)+
};
}
impl_single_insertable! {
impl crate::epub::metadata::EpubVersion,
impl crate::ebook::element::Attribute,
impl<'a> crate::ebook::resource::Resource<'a>,
impl<'a> crate::ebook::resource::ResourceKind<'a>,
}
#[cfg(feature = "write")]
impl_single_insertable! {
impl crate::epub::manifest::DetachedEpubManifestEntry,
impl crate::epub::spine::DetachedEpubSpineEntry,
impl crate::epub::toc::DetachedEpubTocEntry,
impl crate::epub::EpubChapter,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Batch<Iter>(pub Iter);
impl<T, I: Into<T>, It: IntoIterator<Item = I>> Many<T> for Batch<It> {
type Iter = std::iter::Map<It::IntoIter, fn(I) -> T>;
fn iter_many(self) -> Self::Iter {
self.0.into_iter().map(Into::into)
}
}
#[cfg(feature = "write")]
pub trait IntoOption<T> {
fn into_option(self) -> Option<T>;
}
#[cfg(feature = "write")]
mod write {
use crate::input::IntoOption;
impl<T> IntoOption<T> for Option<T> {
fn into_option(self) -> Option<T> {
self
}
}
impl IntoOption<String> for &str {
fn into_option(self) -> Option<String> {
Some(self.to_owned())
}
}
impl IntoOption<String> for &String {
fn into_option(self) -> Option<String> {
Some(self.to_owned())
}
}
impl IntoOption<String> for String {
fn into_option(self) -> Option<String> {
Some(self)
}
}
impl IntoOption<String> for std::borrow::Cow<'_, str> {
fn into_option(self) -> Option<String> {
Some(self.into_owned())
}
}
impl IntoOption<String> for crate::ebook::toc::TocEntryKind<'_> {
fn into_option(self) -> Option<String> {
Some(self.as_str().to_owned())
}
}
}