pub trait Pipeline<In, Out = In> {
fn apply(self, value: In) -> Out;
}
impl<F, In, Out> Pipeline<In, Out> for F
where
F: FnOnce(In) -> Out,
{
fn apply(self, value: In) -> Out { self(value) }
}
pub trait Xtend: Sized {
fn xmap<O>(self, func: impl FnOnce(Self) -> O) -> O { func(self) }
fn xtap(mut self, func: impl FnOnce(&mut Self)) -> Self {
func(&mut self);
self
}
fn xprint(self) -> Self
where
Self: std::fmt::Display,
{
println!("{}", self);
self
}
fn xprint_debug(self) -> Self
where
Self: std::fmt::Debug,
{
println!("{:?}", self);
self
}
fn xprint_debug_formatted(self, prefix: impl AsRef<str>) -> Self
where
Self: std::fmt::Debug,
{
println!("{}: {:#?}", prefix.as_ref(), self);
self
}
fn xtap_mut(&mut self, func: impl FnOnce(&mut Self)) -> &mut Self {
func(self);
self
}
fn xpipe<P: Pipeline<Self, O>, O>(self, pipeline: P) -> O {
pipeline.apply(self)
}
fn xref(&self) -> &Self { self }
fn xmut(&mut self) -> &mut Self { self }
fn xok<E>(self) -> Result<Self, E> { Ok(self) }
fn xsome(self) -> Option<Self> { Some(self) }
fn xinto<T: From<Self>>(self) -> T { T::from(self) }
fn xfmt_debug(&self) -> String
where
Self: std::fmt::Debug,
{
format!("{:?}", self)
}
fn xfmt(&self) -> String
where
Self: std::fmt::Display,
{
format!("{}", self)
}
}
impl<T: Sized> Xtend for T {}
pub trait XtendIter<T>: Sized + IntoIterator<Item = T> {
fn xmap_each<O>(self, func: impl FnMut(T) -> O) -> Vec<O> {
self.into_iter().map(func).collect()
}
fn xtry_filter_map<O, E>(
self,
mut func: impl FnMut(T) -> Result<Option<O>, E>,
) -> Result<Vec<O>, E> {
let mut out = Vec::new();
for item in self.into_iter() {
match (func)(item) {
Ok(Some(o)) => out.push(o),
Ok(None) => {}
Err(e) => return Err(e),
}
}
Ok(out)
}
}
#[extend::ext(name=XtendBool)]
pub impl bool {
fn xmap_true<O>(&self, func: impl FnOnce() -> O) -> Option<O> {
if *self { Some(func()) } else { None }
}
fn xmap_false<O>(&self, func: impl FnOnce() -> O) -> Option<O> {
if !*self { Some(func()) } else { None }
}
}
impl<T: Sized, I: IntoIterator<Item = T>> XtendIter<T> for I {}
pub trait XtendVec<T> {
fn xtend<I: IntoIterator<Item = T>>(self, iter: I) -> Self;
fn xpush(self, item: T) -> Self;
}
impl<T, T2> XtendVec<T> for T2
where
T2: AsMut<Vec<T>>,
{
fn xtend<I: IntoIterator<Item = T>>(mut self, iter: I) -> Self {
self.as_mut().extend(iter);
self
}
fn xpush(mut self, item: T) -> Self {
self.as_mut().push(item);
self
}
}
pub trait XtendString {
fn xtend(self, item: impl AsRef<str>) -> Self;
}
impl XtendString for String {
fn xtend(mut self, item: impl AsRef<str>) -> Self {
self.push_str(item.as_ref());
self
}
}