context_manager

Crates.iocontext_manager
lib.rscontext_manager
version
sourcesrc
created_at2025-01-21 23:12:47.729133+00
updated_at2025-01-28 23:37:41.5272+00
descriptionPython's like context_managers in Rust
homepage
repositoryhttps://github.com/macisamuele/context_manager_rs
max_upload_size
id1525912
Cargo.toml error:TOML parse error at line 17, column 1 | 17 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include`
size0
Samuele Maci (macisamuele)

documentation

https://docs.rs/context_manager_macro

README

Context Manager

Build and test crates.io docs.rs

Library offering an easy access Python like decorators in rust

Via this library we can easily alter the content of a defined function, by injecting code to be executed before/after the original function, without altering the original function itself.

For example, let's assume that we are interested on logging the duration of the execution of a function.

fn function_to_be_decorated() -> usize {
    # let do_something_expensive = || 1234;
    do_something_expensive()
}

In order to achieve so we would need to manually modify it similarly to

fn function_to_be_decorated() -> usize {
    # let do_something_expensive = || 1234;
    let start = std::time::Instant::now();
    let return_value = do_something_expensive();
    println!("Duration of function_to_be_decorated is: {}ms", start.elapsed().as_millis());
    return_value
}

As far as this could be very simple, it is tedious and requires to actually modify the original function. While having a simple decorator that would do it for us would be much more convenient. Leading to something like

# use context_manager::SyncWrapContext;
# struct PrintDuration;
# impl<T> SyncWrapContext<T> for PrintDuration { fn new() -> Self { Self } }
#[context_manager::wrap(PrintDuration)]
fn function_to_be_wrapped() -> usize {
    # let do_something_expensive = || 1234;
    do_something_expensive()
}

How does the library work internally?

The library exposes 2 main traits that allows users to customize the wrapping logic

  • [SyncWrapContext] for synchronous context management (which is supported for decorating sync and async functions)
  • [AsyncWrapContext] for asynchronous context management (which is supported ONLY for async functions)

and 2 main attribute macros ([wrap] and [async_wrap]) that allow an easy plug-and-play of the logic into the code

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Commit count: 13

cargo fmt