Skip to content

appcypher/lazy-attribute

lazy-attribute

Crate Code Coverage Build Status License-Apache License-MIT Docs

lazy-attributes provides attribute macros for simplifying working with lazily evaluated functions.

Functions decorated with #[lazy_ref] will only be executed the first time they are called. On subsequent calls, the cached return value is returned.

Outline

Usage

Add this to your Cargo.toml:

[dependencies]
lazy-attribute = "0.1"

Examples

With lazy_attribute::lazy_ref, you can annotate a function that you want to lazily evaluate:

use lazy_attribute::lazy_ref;

#[lazy_ref]
fn get_string() -> String {
    println!("Called once!");
    String::from("Hello, world!")
}

fn main() {
    println!("{}", get_string());  // Outputs: Called once! Hello, world!
    println!("{}", get_string());  // Outputs: Hello, world!
}

The first time the function is called, it will be evaluated and its result will be cached. Subsequent calls will return the cached result.

lazy_ref macro roughly desugars the get_string function to:

static __lazy_static_get_string: OnceCell<String> = OnceCell::new();

fn get_string() -> &'static String {
    __lazy_static_get_string.get_or_init(|| {
        println!("Called once!");
        String::from("Hello, world!")
    })
}

With async feature enabled, lazy_ref can also be used with async functions:

use lazy_attribute::lazy_ref;

#[lazy_ref]
async fn get_string() -> String {
    println!("Called once!");
    String::from("Hello, world!")
}

#[tokio::main]
async fn main() {
    println!("{}", get_string().await);  // Outputs: Called once! Hello, world!
    println!("{}", get_string().await);  // Outputs: Hello, world!
}

Caveats

  • lazy_* macros do not support functions with arguments. You will get an error telling you arguments are not supported.

Crate Features

  • async - Enables support for lazily evaluating async functions.

Crate Features

  • async - Enables support for lazily evaluating async functions.

Contributing

Feedback welcome! Check the contributing guide to you want to get involved. We also adhere to our Code of Conduct.

Testing the Project

  • Run tests

    cargo test --all-features

Formatting

For formatting Rust in particular, please use cargo +nightly fmt as it uses specific nightly features we recommend. Make sure you have nightly installed.

Pre-commit Hook

This project recommends using pre-commit for running pre-commit hooks. Please run this before every commit and/or push.

  • Once installed, Run pre-commit install and pre-commit install --hook-type commit-msg to setup the pre-commit hooks locally. This will reduce failed CI builds.

  • If you are doing interim commits locally, and for some reason if you don't want pre-commit hooks to fire, you can run git commit -a -m "Your message here" --no-verify.

License

This project is licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.