Impl-tools
A set of helper macros
Macros
Autoimpl
#[autoimpl]
is a partial replacement for #[derive]
, supporting:
- Explicit
where
clause on generic parameters - No implicit bounds on generic parameters beyond those required by the type
- Traits like
Deref
byusing
a named field - Traits like
Debug
mayignore
named fields
#[autoimpl]
may also be used on trait definitions to impl for specified types
supporting Deref
.
Unlike alternatives, #[autoimpl]
has minimal and intuitive syntax.
use autoimpl;
use Debug;
// Impl Animal for Box<T> where T: Animal + ?Sized
// Impl Debug for Named<T, A: Animal> omitting field animal from output
// Impl Deref and DerefMut to field animal for Named<T, A: Animal>
New-type wrappers
A combination of Deref
on the new-type and trait-reimplementation on the
trait allows succinct new-type patterns:
use autoimpl;
use Arc;
// Impl Foo for &T, &mut T and Arc<T>
// Optional: impl Foo for NewFoo (requires NewFoo: Deref<Target = T>)
// Impl Deref and DerefMut to a Target which itself supports Foo
;
// Impl Deref and DerefMut to a Target which itself supports Foo
;
See tests/newtype.rs
for more variants of this pattern.
Impl Default
#[impl_default]
implements std::default::Default
:
!
impl_scope
Note: #[impl_default]
is matched within an impl_scope!
regardless of imports.
Impl Self
#[impl_self]
provides impl Self
syntax, avoiding the
need to repeat generics when writing impls on a local type definition.
This supercedes impl_scope!
(except regarding macro@impl_default
).
use Display;
Note that struct NamedThing
is defined directly within the outer namespace,
not within the mod NamedThing
. This is a hack required to ensure the contents
use valid Rust syntax and are thus formattable using cargo fmt
.
Impl Anon
impl_anon!
is a function-like macro to construct a single-use struct with
custom implementations (similar: RFC#2604).
Example:
use fmt;
Extensibility
Rust's #[derive]
macro is extensible via #[proc_macro_derive]
in a proc-macro
crate.
Our macros cannot be extended in the same way, but they can be extended via a new front-end:
- Create a copy of the
impl-tools
crate to create a new "front-end" (proc-macro
crate). This crate is contains only a little code over theimpl-tools-lib
crate. - To extend
#[autoimpl]
, write an impl ofImplTrait
and add it to the attribute's definition. To extend#[impl_self]
, write an impl ofScopeAttr
and add it to the macro's definition. - Depend on your new front end crate instead of
impl-tools
.
For an example of this approach, see kas-macros.
Alternatives
Derive alternatives
Both Educe and Derivative
have similar functionality: the ability to implement standard traits with more flexibility than
libstd's #[derive]
.
In comparison, impl-tools' #[autoimpl]
has cleaner syntax but is less flexible:
// impl-tools:
Note: #[derive]
and Derivative
add bounds like S: PartialEq, T: PartialEq
on generic parameters by default; Educe
and impl-tools
do not.
Derive extensions
derive_more isn't exactly an "alternative", simply
supporting #[derive]
for more standard traits such as Add
and From
.
This is not (currently) supported by #[autoimpl]
(or, to my knowledge, any alternative).
auto_impl allows implementing a trait for reference types
(&
, &mut
, Box
, Rc
, Arc
) as well as function types. The former (reference types) is
supported by #[autoimpl]
(and is slightly more general):
// auto_impl:
// impl-tools:
derive-where is a variant of the
standard #[derive]
macro supporting custom generic bounds.
(This offers a subset of the functionality of #[autoimpl]
).
Copyright and Licence
The COPYRIGHT file includes a list of contributors who claim copyright on this project. This list may be incomplete; new contributors may optionally add themselves to this list.
The impl-tools library is published under the terms of the Apache License, Version 2.0. You may obtain a copy of this licence from the LICENSE file or on the following webpage: https://www.apache.org/licenses/LICENSE-2.0