Return Number types , String and Boolean for a generic function

Hi I am trying to make a utility method with a generic function to avoid some boiler plate like so

pub type HaystackRestResult<T> = std::result::Result<T, HaystackRestError>;

fn val_to_core_type<T>(val: &Val) -> HaystackRestResult<T> 
    where T:std::fmt::Debug {

    let option: Option<Token> = val.cast_to_type();

    if option.is_none() {
        return Err(HaystackRestError::BadRequestError{error: "token cast failed".to_string()});
    }

    let result: T = match option.unwrap() {
        Token::EscapedString(s) => s,
        Token::IntegerNumber(n, _units) => n.number,
        Token::FloatNumber(n, _display) => n.number,

        _ => {
            return Err(HaystackRestError::BadRequestError{error: "type error".to_string()});
        },
    };

    Ok(result)
}

// example use

let host_result: HaystackRestResult<String> = val_to_core_type(&row[0]);
let host = translate_to_status!(host_result);

let port_result: HaystackRestResult<u64> = val_to_core_type(&row[1]);
let port = translate_to_status!(port_result);

Trouble is I get the error

fn val_to_core_type<T>(val: &Val) -> HaystackRestResult<T> 
    |                     - this type parameter
...
698 |         Token::EscapedString(s) => s,
    |                                    ^ expected type parameter `T`, found struct `std::string::String`
    |
    = note: expected type parameter `T`
                       found struct `std::string::String`

For more information about this error, try `rustc --explain E0308`.

Maybe I should use a macro for something like this but I want to understand the generic issue as well.
Can my string and numbers here both be treated as a T. ?

Thanks

You could have TryFrom<Token> impls from for all the relevant types (String, u8, u32, f32, f64, etc), then use that to perform the fallible conversion.
The val_to_core_type function would then require where T:std::fmt::Debug + TryFrom<Token>.

Here is what the TryFrom impl would look like for String: Rust Playground

1 Like