18 releases

0.0.18 Nov 8, 2024
0.0.17 Jun 14, 2024
0.0.16 Jan 16, 2024
0.0.15 Oct 17, 2023
0.0.3 Dec 14, 2021

#111 in Rust patterns

Download history 144258/week @ 2025-01-19 170689/week @ 2025-01-26 175866/week @ 2025-02-02 181565/week @ 2025-02-09 178935/week @ 2025-02-16 224249/week @ 2025-02-23 227164/week @ 2025-03-02 237095/week @ 2025-03-09 226457/week @ 2025-03-16 249571/week @ 2025-03-23 245094/week @ 2025-03-30 270882/week @ 2025-04-06 239441/week @ 2025-04-13 234363/week @ 2025-04-20 213975/week @ 2025-04-27 239000/week @ 2025-05-04

934,276 downloads per month
Used in 74 crates (10 directly)

MIT license

190KB
3.5K SLoC

Virtue, a sinless derive macro helper

Goals

  • Zero dependencies, so fast compile times
  • No other dependencies needed
  • Declarative code generation
  • As much typesystem checking as possible
  • Build for modern rust: 1.57 and up
  • Build with popular crates in mind:
  • Will always respect semver. Minor releases will never have:
    • Breaking API changes
    • MSRV changes

Example

use virtue::prelude::*;

#[proc_macro_derive(YourDerive, attributes(some, attributes, go, here))]
pub fn derive_your_derive(input: TokenStream) -> TokenStream {
    derive_your_derive_inner(input)
        .unwrap_or_else(|error| error.into_token_stream())
}

fn derive_your_derive_inner(input: TokenStream) -> Result<TokenStream> {
    // Parse the struct or enum you want to implement a derive for
    let parse = Parse::new(input)?;
    // Get a reference to the generator
    let (mut generator, body) = parse.into_generator();
    match body {
        Body::Struct(body) => {
            // Implement your struct body here
            // See `Generator` for more information
            generator.impl_for("YourTrait")?
                    .generate_fn("your_fn")
                    .with_self_arg(FnSelfArg::RefSelf)
                    .body(|fn_body| {
                        fn_body.push_parsed("println!(\"Hello world\");");
                    })?;
        },
        Body::Enum(body) => {
            // Implement your enum body here
            // See `Generator` for more information
            generator.impl_for("YourTrait")?
                    .generate_fn("your_fn")
                    .with_self_arg(FnSelfArg::RefSelf)
                    .body(|fn_body| {
                        fn_body.push_parsed("println!(\"Hello world\");");
                    })?;
        },
    }
    generator.finish()
}

Will generate

impl YourTrait for <Struct or Enum> {
    fn your_fn(&self) { // .generate_fn("your_fn").with_self_arg(FnSelfArg::RefSelf)
        println!("Hello world"); // fn_body.push_parsed(...)
    }
}

Dependencies

OSZAR »