[][src]Crate blanket

🧣 blanket Star me

A simple macro to derive blanket implementations for your traits.

TravisCI Codecov License Source Crate Documentation Changelog GitHub issues

🗺️ Overview

The Rust standard library has plenty of traits, but they shine in how well they integrate with new types. Declare an implementation of std::io::Write for a type T, and you also get it for &mut T and Box<T>! This however translates into a lot of boilerplate code that can be hard to maintain, which is why many crates don't over the same convenience implementations.

This is where blanket comes in! This crate helps you build the same kind of blanket implementations for your own traits with as least additional code as possible: in fact, this is as close as what a derive macro would look like for a trait item.

🔌 Usage

blanket exports a single eponymous attribute macro, which can be imported simply after the crate has been added to the Cargo.toml dependencies:

extern crate blanket;
use blanket::blanket;

#[blanket(derive(...))]

Use this macro attribute to derive a blanket implementation for a trait, provided the trait methods fit the constraints for that derive, such as only declaring methods with &self of &mut self as their receiver. The following derives are available:

DeriveImpl blockfn (&self)fn (&mut self)fn (self)
Refimpl<T: Trait + ?Sized> Trait for &T✔️
Mutimpl<T: Trait + ?Sized> Trait for &mut T✔️✔️
Boximpl<T: Trait> Trait for Box<T>✔️✔️✔️

#[blanket(default = "...")]

blanket can delegate default implementations of trait methods to functions of another module. This can be useful for some traits such as visitors to provide a default behaviour as an external function, such as what syn::visit is doing.

The following example implements a very simple visitor trait for types able to process a &str char-by-char.

This example is not tested
extern crate blanket;
use blanket::blanket;

#[blanket(default = "visitor")]
trait Visitor {
    fn visit_string(&self, s: &str);
    fn visit_char(&self, c: char);
}

mod visitor {
    use super::Visitor;

    pub fn visit_string<V: Visitor + ?Sized>(v: &V, s: &str) {
        for c in s.chars() {
            v.visit_char(c);
        }
    }

    pub fn visit_char<V: Visitor + ?Sized>(v: &V, c: char) {}
}

blanket will check that all methods are declared without a default block, and then create a default implementation for all of the declared methods, generating the following code:

This example is not tested
trait Visitor {
    fn visit_string(&self, s: &str) {
      visitor::visit_string(self, s)
    }
    fn visit_char(&self, c: char) {
      visitor::visit_char(self, c)
    }
}

✒️ To-Do

  • [ ] Add support for traits with generic arguments.
  • [ ] Add support for #[derive(Rc)]
  • [ ] Add support for #[derive(Arc)]

📋 Changelog

This project adheres to Semantic Versioning and provides a changelog in the Keep a Changelog format.

📜 License

This library is provided under the open-source MIT license.

Attribute Macros

blanket