Constraining by non-trait functions


#1

I have a case where I’d like to constrain a generic to types that implement a number of functions, say get(&self, &K) and insert(&self, K, V).

The solution I’ve been working on is creating a type describing the methods and implementing it explicitly for the types I care about:

trait GetAndSettable<K,V> {
    fn get(&self, k: &K) -> Option<V>;
    fn insert(&self, k: K, v: V) -> Option<V>;
}

The problem is that this requires basically implementing proxy methods for each type, which is annoying

impl<K,V> GetAndSettable<K,V> for HashMap<K,V> {
    fn get(&self, k: &K) -> Option<V> { 
        HashMap<K,V>::get(self, k)
    }
    fn insert(&self, k: K, v: V) -> Option<V> { 
        HashMap<K,V>::insert(self, k, v) 
    }
}

Is there a better way to do this?


#2

No. Rust doesn’t support adhoc structure-level type bounds.

To ease pain to some degree you can try to create a macro to auto-implement your trait’s methods
to proxy to already existing methods of underlying type.


#3

I don’t mind being explicit about which types implement the trait, I would just prefer to be able to do something like

impl<K,V> GetAndSettable<K,V> for HashMap<K,V>;

I tried using default implementations, but as far as I can tell there’s no way to get a handle on the implementing type from within a generic implementation (Self is bound to the trait in that context).

OK, well macros are probably a better solution, thanks!