The short answer is that you cannot. Check out the function prototype:
fn convert<T>(e: &Value) -> T
This suggests that for any T that the caller selects, the function should return this. This will entail a very large number of features, including any type ever created by any user of this code.
However, there is a solution to your problem. You just need to see how the standard library implements str::parse :
fn parse<F>(&self) -> Result<F, F::Err> where F: FromStr { FromStr::from_str(self) }
FromStr is a true hero, and many implement it. Any type that implements FromStr can be used with parse .
I believe that you can use FromStr for your case, because your code does not make any sense. ^ _ ^ Your sample code:
let i = query::<i32>("i");
Indicates the type twice - once as a parameter of type <i32> and once as a string "i" . This is rather strange, so I assume that in fact the argument is the name of the key-value pair. This makes me think about how the Rust Postgres box works (pseudocode shown):
let id: i32 = row.get(0); let name: String = row.get(1);
I believe that you can combine on FromStr and add some template:
use std::collections::HashMap; use std::str::FromStr; struct ConfigFile { raw: HashMap<String, String>, } impl ConfigFile { fn read_from_disk() -> Self { let mut map = HashMap::new(); map.insert("name".into(), "Anna".into()); map.insert("points".into(), "210".into()); map.insert("debugging".into(), "true".into()); ConfigFile { raw: map } } fn get<T>(&self, name: &str) -> Option<T> where T: FromStr { self.raw.get(name).and_then(|v| v.parse().ok()) } } fn main() { let conf = ConfigFile::read_from_disk(); let n: String = conf.get("name").unwrap(); let p: i32 = conf.get("points").unwrap(); let d: bool = conf.get("debugging").unwrap(); println!("{} has {} points, {}", n, p, d); }