Reputation: 2174
I need to write some Environment getters in rust
#[allow(non_camel_case_types)]
pub enum ENV {
TEST_1,
TEST_2,
}
impl ENV {
pub fn as_str(&self) -> &'static str {
match *self {
ENV::TEST_1 => "TEST_1",
ENV::TEST_2 => "TEST_2",
}
}
}
pub fn var<T: Into<String>>(key: ENV, def: T) -> String {
return std::env::var(key.as_str()).unwrap_or(def.into());
}
pub fn var_int<T: Into<u16>>(key: ENV, def: T) -> u16 {
return std::env::var(key.as_str())
.map(|v| v.parse::<u16>().ok())
.unwrap_or(None)
.unwrap_or(def.into());
}
Now I do not want to write getters for u32
u16
... is there anything working with generics to let the caller define the type?
let port: u16 = var(ENV::TEST_1, 80);
Upvotes: 0
Views: 134
Reputation: 42572
Now I do not want to write getters for
u32
,u16
... is there anything working with generics to let the caller define the type?
You can infer that there is from str::parse
which can return different types parsed from strings based on the caller's decision. So all you need to do is work from there: parse
works based on FromStr
, so instead of a hardcoded output you need one bound to FromStr
, and your default needs to be convertible to that as well. Then it's just jiggling around to get something working:
pub fn var_int<Q: FromStr, T: Into<Q>>(key: ENV, def: T) -> Q {
std::env::var(key.as_str()).ok()
.and_then(|v| v.parse::<Q>().ok())
.unwrap_or_else(|| def.into())
}
Upvotes: 2