Skip to content

Abstract key lookup into a trait for Family::get_or_create #157

Open
@cheshirskycode

Description

@cheshirskycode

Family::get_or_create forces to clone labels data for the lookup of a counter. Example:

#[derive(Clone, Eq, Hash, PartialEq, EncodeLabelSet)]
struct RequestLabels {
    host: String,
    api: String,
}

fn test() {
    let family = Family::<RequestLabels, Counter>::default();

    fn call(host: &str, api: &str, family: &Family<RequestLabels, Counter>) {
        let labels = RequestLabels {
            host: host.to_string(),
            api: api.to_string(),
        };

        let counter = family.get_or_create(&labels);
        counter.inc();
    }
}

I must create RequestLabels with cloning host and api values instead of getting counter by data references. The Family struct uses the std::collections::HashMap inside, which doesn't allow any other way to look up.

It would be great to have the ability to write something like this:

#[derive(Clone, Eq, Hash, PartialEq, EncodeLabelSet)]
struct RequestLabels {
    host: String,
    api: String,
}

struct RequestLabelsQ<'a> {
    host: &'a str,
    api: &'a str,
}

impl Equivalent<RequestLabels> for RequestLabelsQ<'_> {
    fn equivalent(&self, key: &RequestLabels) -> bool {
        self.host == key.host && self.api == key.api
    }
}

fn test() {
    let family = Family::<RequestLabels, Counter>::default();

    fn call(host: &str, api: &str, family: &Family<RequestLabels, Counter>) {
        let labels = RequestLabelsQ {
            host, api,
        };

        let counter = family.get_or_create(&labels);
        counter.inc();
    }
}

This will require using hashbrown instead of std::collections::HashMap (but actually std map is wrapper on hashbrown).
Equivalent
HashMap::get
Also, it will affect the definition of Family::get_or_create but the behavior should be the same.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions