Search code examples
rust

Function that accepts either owned data of type T or a ref to data of type T and returns original data or clone of referenced data respectively


How can you write a function that accepts either data of type T or a reference to data of type T, and returns either the original data or a clone of the referenced data respectively? Something like this:

fn foo(input: T or &T) -> T {
    if input is &T {
        input.clone()
    } else {
        input
    }
}

Solution

  • You want to pass in something that can be converted into Cow:

    use std::borrow::Cow;
    
    fn main() {
        let owned = String::from("Hello world.");
        let _clone = owned.clone();
        let borrowed = &_clone;
        assert_eq!(borrowed_or_owned(owned), "Hello world.".to_string());
        assert_eq!(borrowed_or_owned(borrowed), "Hello world.".to_string());
    }
    
    fn borrowed_or_owned<'a, T>(value: impl Into<Cow<'a, T>>) -> <T as ToOwned>::Owned
    where
        T: ToOwned + 'a + ?Sized,
    {
        value.into().into_owned()
    }
    

    Playground