Skip to content

Instantly share code, notes, and snippets.

@mikeyhew
Created January 7, 2019 00:55
Show Gist options
  • Save mikeyhew/af6eba0c6d450acdbb5faf0ffa6fd894 to your computer and use it in GitHub Desktop.
Save mikeyhew/af6eba0c6d450acdbb5faf0ffa6fd894 to your computer and use it in GitHub Desktop.
A potential new API for ty::Binder
/// A number of lifetime and type parameters that a type is bound with
#[derive(Copy, Clone, Debug)]
pub struct Binder {
num_lifetimes: u32,
num_types: u32,
}
impl Binder {
pub fn bind<T>(self, value: T) -> Bound<T> {
Bound {
binder: self,
value,
}
}
pub fn dummy() -> Self {
Self {
num_lifetimes: 0,
num_types: 0,
}
}
}
/// A bound type, e.g. `for<'a, T> &'a T`. Contains a Binder with the number of
/// lifetime and type parameters that it is bound with
#[derive(Copy, Clone, Debug)]
pub struct Bound<T> {
binder: Binder,
value: T,
}
impl<T> Bound<T> {
pub fn unbind(self) -> (Binder, T) {
(self.binder, self.value)
}
pub fn skip_binder(&self) -> &T {
&self.value
}
pub fn map_bound<U> (self, f: impl FnOnce(T) -> U) -> Bound<U> {
let (binder, value) = self.unbind();
f(value).bind_with(binder)
}
}
pub trait Bind: Sized {
fn bind_with(self, binder: Binder) -> Bound<Self> {
Bound {
binder,
value: self,
}
}
fn bind_with_dummy(self) -> Bound<Self> {
self.bind_with(Binder::dummy())
}
}
impl<T> Bind for T {}
fn main() {
let bound = "1".bind_with_dummy();
let bound = bound.map_bound(|s| s.parse::<i32>().unwrap());
println!("{:#?}", bound);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment