use std::fmt;
use std::fmt::Display;
use std::path::PathBuf;
use std::str::FromStr;
use crate::string::{LocaleString, ParseError};
#[derive(Debug, PartialEq)]
pub enum Locale {
POSIX,
Path(PathBuf),
String(LocaleString),
}
const L_C: &'static str = "C";
const L_POSIX: &'static str = "POSIX";
const L_PATH_SEP: &'static str = "/";
impl Display for Locale {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}",
match self {
Locale::POSIX => L_POSIX.to_string(),
Locale::Path(s) => s.to_str().unwrap().to_string(),
Locale::String(s) => s.to_string(),
}
)
}
}
impl FromStr for Locale {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.len() == 0 {
return Err(ParseError::EmptyString);
}
match s {
L_C => Ok(Locale::POSIX),
L_POSIX => Ok(Locale::POSIX),
_ => {
if s.starts_with(L_PATH_SEP) {
match PathBuf::from_str(s) {
Ok(p) => Ok(Locale::Path(p)),
Err(_) => Err(ParseError::InvalidPath),
}
} else {
Ok(Locale::String(LocaleString::from_str(s)?))
}
}
}
}
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;
use super::*;
#[test]
fn test_posix_to_string() {
assert_eq!(Locale::POSIX.to_string(), "POSIX");
}
#[test]
fn test_path_to_string() {
let _path = PathBuf::from_str("/usr/share/locale/en_US");
}
#[test]
fn test_string_to_string() {
let locale = LocaleString::new("en".to_string())
.with_territory("US".to_string())
.with_code_set("UTF-8".to_string());
assert_eq!(locale.to_string(), "en_US.UTF-8");
}
#[test]
fn test_posix_from_string() {
match Locale::from_str("POSIX") {
Ok(Locale::POSIX) => (),
_ => panic!("expecting Locale::POSIX"),
}
match Locale::from_str("C") {
Ok(Locale::POSIX) => (),
_ => panic!("expecting Locale::POSIX (C)"),
}
}
#[test]
fn test_path_from_string() {
match Locale::from_str("/usr/share/locale/en_US") {
Ok(Locale::Path(p)) => assert_eq!(p.to_str(), Some("/usr/share/locale/en_US")),
_ => panic!("expecting Locale::Path"),
}
}
#[test]
fn test_string_from_string() {
println!("{:#?}", Locale::from_str("en_US.UTF-8"));
match Locale::from_str("en_US.UTF-8") {
Ok(Locale::String(ls)) => {
assert_eq!(ls.get_language_code(), "en");
assert_eq!(ls.get_territory(), Some("US".to_string()));
assert_eq!(ls.get_code_set(), Some("UTF-8".to_string()));
}
_ => panic!("expecting Locale::String"),
}
}
}