Skip to content

Instantly share code, notes, and snippets.

@Caellian
Last active September 23, 2023 01:30
Show Gist options
  • Save Caellian/8bfb99c0662658181a78d16b77a8a44f to your computer and use it in GitHub Desktop.
Save Caellian/8bfb99c0662658181a78d16b77a8a44f to your computer and use it in GitHub Desktop.
Apply mutates a value using a closure and then instantly returns it. This is useful for handling Ok/Some case in scenarios where type can be either Result/Option<T> or T directly, based on another type generic, but that requires `specializatation` feature.
pub trait Apply {
type ValidValue;
fn apply(self, consumer: impl Fn(&mut Self::ValidValue)) -> Self
where
Self: Sized;
fn apply_ref(&mut self, consumer: impl Fn(&mut Self::ValidValue)) -> &mut Self;
}
default impl<T> Apply for T {
type ValidValue = Self;
fn apply(mut self, consumer: impl Fn(&mut Self::ValidValue)) -> Self
where
Self: Sized,
{
unsafe {
consumer(core::mem::transmute(&mut self));
}
self
}
fn apply_ref(&mut self, consumer: impl Fn(&mut Self::ValidValue)) -> &mut Self {
unsafe {
consumer(core::mem::transmute(&mut *self));
}
self
}
}
impl<T> Apply for Option<T> {
type ValidValue = T;
fn apply(mut self, consumer: impl Fn(&mut Self::ValidValue)) -> Self
where
Self: Sized,
{
match &mut self {
Some(it) => consumer(it),
_ => {}
}
self
}
fn apply_ref(&mut self, consumer: impl Fn(&mut Self::ValidValue)) -> &mut Self {
match self {
Some(it) => consumer(it),
_ => {}
}
self
}
}
impl<T, E> Apply for Result<T, E> {
type ValidValue = T;
fn apply(mut self, consumer: impl Fn(&mut Self::ValidValue)) -> Self
where
Self: Sized,
{
match &mut self {
Ok(it) => consumer(it),
_ => {}
}
self
}
fn apply_ref(&mut self, consumer: impl Fn(&mut Self::ValidValue)) -> &mut Self {
match self {
Ok(it) => consumer(it),
_ => {}
}
self
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment