I am using an enum for each continent in my Rust program. Asia, Europe, etc. However this enum corresponds to an integer in the database definition, it can be constructed from an external source and can be transformed to another "type" if requested.
For example
enum ContinentKind {
Asia,
Europe,
Africa,
America,
Oceania,
}
impl ContinentKind {
fn new(external_input: &str) -> Result<ContinentKind, String> {
match external_input {
"ASIA" => Ok(ContinentKind::Asia),
"EUROPE" => Ok(ContinentKind::Europe),
"AFRICA" => Ok(ContinentKind::Africa),
"AMERICA" => Ok(ContinentKind::America),
"OCEANIA" => Ok(ContinentKind::Oceania),
_ => Err("Wrong external input".to_string()),
}
}
fn id(&self) -> u32 {
match *self {
ContinentKind::Asia => 1,
ContinentKind::Europe => 2,
ContinentKind::Africa => 3,
ContinentKind::America => 4,
ContinentKind::Oceania => 5,
}
}
fn api_string(&self) -> String {
match *self {
ContinentKind::Asia => String::from("I love Asia"),
ContinentKind::Europe => String::from("I travel to Europe"),
ContinentKind::Africa => String::from("Hello Africa"),
ContinentKind::America => String::from("North and South America"),
ContinentKind::Oceania => String::from("O C E A N I A"),
}
}
}
So I can use ContinentKind::Asia in most of the time, but I am using the id(&self) method to take an integer and save to database, or api_string(&self) to return a string in my http server.
Each continent, has a type, an integer, an external definition and a description string.
Asia, "ASIA", 1, "I love Asia"
Europe, "EUROPE", 2 "I travel to Europe"
Africa, "AFRICA", 3, "Hello Africa"
America, "AMERICA", 4, "North and South America"
Oceania "OCEANIA", 5, "O C E A N I A"
With the first glance the code works when I am calling, but I was wondering if there is a better way to do it, that takes less code.
let my_type = ContinentKind::America;
println!("{}", my_type.id());
println!("{}", my_type.api_string());
let another_type = ContinentKind::new("AFRICA");
match another_type {
Ok(v)=> println!("{}", v.id()),
_ => println!("an error happend"),
}
And what I mean by that is to finally create a struct like this:
struct Continent {
id: u32,
kind: ContinentKind,
externaL_str : String,
internal_str: String,
}
that has 2 constructs, from_id or from_external_str and have the type nested.
For example:
#[derive(Debug)]
struct Continent {
id: u32,
kind: ContinentKind,
external_str : String,
internal_str: String,
}
impl Continent {
fn from_external_string(external_input: &str) -> Result<Continent, String> {
match external_input {
"ASIA" => Ok(Continent{id: 1, kind:ContinentKind::Asia, external_str: String::from("ASIA"), internal_str:String::from("I love Asia")}),
"EUROPE" => Ok(Continent{id: 2, kind:ContinentKind::Europe, external_str: String::from("EUROPE"), internal_str:String::from("I travel to Europe")}),
"AFRICA" => Ok(Continent{id: 3, kind:ContinentKind::Africa, external_str: String::from("AFRICA"), internal_str:String::from("Hello Africa")}),
"AMERICA" => Ok(Continent{id: 4, kind:ContinentKind::America, external_str: String::from("AMERICA"), internal_str:String::from("North and South America")}),
"OCEANIA" => Ok(Continent{id: 5, kind:ContinentKind::Oceania, external_str: String::from("OCEANIA"), internal_str:String::from("O C E A N I A")}),
_ => Err("Wrong external input".to_string()),
}
}
fn from_database_id(id: u32) -> Result<Continent, String> {
match id {
1 => Ok(Continent{id: 1, kind:ContinentKind::Asia, external_str: String::from("ASIA"), internal_str:String::from("I love Asia")}),
2 => Ok(Continent{id: 2, kind:ContinentKind::Europe, external_str: String::from("EUROPE"), internal_str:String::from("I travel to Europe")}),
3 => Ok(Continent{id: 3, kind:ContinentKind::Africa, external_str: String::from("AFRICA"), internal_str:String::from("Hello Africa")}),
4 => Ok(Continent{id: 4, kind:ContinentKind::America, external_str: String::from("AMERICA"), internal_str:String::from("North and South America")}),
5 => Ok(Continent{id: 5, kind:ContinentKind::Oceania, external_str: String::from("OCEANIA"), internal_str:String::from("O C E A N I A")}),
_ => Err("Wrong external input".to_string()),
}
}
}