A better way to handle type matching


#1

Trying to infer a more specific type from a string.

Examples:

"123" -> i64
"123.4" -> f64
"true" -> bool
_ -> string

Is there a more idiomatic way to write this?

#[derive(PartialEq, Debug)]
enum Type {
    Bool(bool),
    String(String),
    Int(i64),
    Float(f64),
}

fn get_type(var: &str) -> Type {
    let i = var.to_string().parse::<i64>();
    if i.is_ok() {
        return Type::Int(i.unwrap());
    }
    let f = var.to_string().parse::<f64>();
    if f.is_ok() {
        return Type::Float(f.unwrap());
    }
    match var {
        "true" => Type::Bool(true),
        "false" => Type::Bool(false),
        _ => Type::String(var.to_string()),
    }
}


mod test {

    use super::*;

    #[test]
    fn test_get_type() {
        assert_eq!(get_type("hello"), Type::String("hello".to_string()));
        assert_eq!(get_type("true"), Type::Bool(true));
        assert_eq!(get_type("false"), Type::Bool(false));
        assert_eq!(get_type("123"), Type::Int(123));
        assert_eq!(get_type("123.0"), Type::Float(123.0));
    }
}

#2

You might try something like this:

#[derive(PartialEq, Debug)]
enum Type {
    Bool(bool),
    String(String),
    Int(i64),
    Float(f64),
}

impl Type {
    fn parse(val: &str) -> Type {
        if let Ok(as_int) = val.parse::<i64>() {
            Type::Int(as_int)
        } else if let Ok(as_float) = val.parse::<f64>() {
            Type::Float(as_float)
        } else {
            match val {
                "true" => Type::Bool(true),
                "false" => Type::Bool(false),
                _ => Type::String(val.to_string()),
            }
        }
    }
}


mod test {

    use super::*;

    #[test]
    fn test_get_type() {
        assert_eq!(Type::parse("hello"), Type::String("hello".to_string()));
        assert_eq!(Type::parse("true"), Type::Bool(true));
        assert_eq!(Type::parse("false"), Type::Bool(false));
        assert_eq!(Type::parse("123"), Type::Int(123));
        assert_eq!(Type::parse("123.0"), Type::Float(123.0));
    }
}

#3

Yeah! That’s what I was looking for.
I knew about if let already but for some reason it didn’t cross my mind to use it in this case. Strange.
Anyway, thanks for that! Huge fan of your podcast by the way.


#4

:thumbsup: Happy to help!