Rust How to pass static Lazy as a parameter

Viewed 113

I have this code to initialize the metrics registry

use once_cell::sync::Lazy;

pub static REQUEST_COUNTER: Lazy<IntCounter> = Lazy::new(|| {
    register_int_counter!("requests_total", "Request counter").expect(REGISTRY_ERR)});
pub static ERROR_COUNTER: Lazy<IntCounter> = Lazy::new(|| {
    register_int_counter!("errors_total", "Error counter").expect(REGISTRY_ERR)});
...

pub fn create_registry() -> Registry {
    let registry = Registry::new();   
    registry.register(Box::new(REQUEST_COUNTER.clone())).expect(REGISTRY_ERR);
    registry.register(Box::new(ERROR_COUNTER.clone())).expect(REGISTRY_ERR);
    ...

    registry
}

I want to extract the repetitive part into a new function

pub fn create_registry() -> Registry {
    ...
    register_collector(&registry, &REQUEST_COUNTER);
    ...
    registry
}

fn register_collector <T> (registry: &Registry, collector: &Lazy<T>) where T: Collector + Clone {
    registry.register(Box::new(collector.clone())).expect(REGISTRY_ERR);
}

but rust compiler shows an error for this function signature:

   |
37 |     registry.register(Box::new(collector.clone())).expect(REGISTRY_ERR);
   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Collector` is not implemented for `&once_cell::sync::Lazy<T>`
   |
   = note: required for the cast to the object type `dyn Collector`

What is the correct signature for "register_collector" function?

1 Answers

register_collector is passed a borrowed Lazy reference, so it needs to be dereferenced with *:

    .register(Box::new((*collector).clone()))
Related