Created
October 6, 2017 15:14
-
-
Save anonymous/9d2535d71f997dba662e942b4b751aec to your computer and use it in GitHub Desktop.
Rust code shared from the playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(try_from)] | |
use std::collections::BTreeMap; | |
use std::fmt::Debug; | |
use std::convert::TryFrom; | |
#[derive(Debug, Clone, PartialEq)] | |
pub enum Value { | |
Double(f64), | |
Text(String), | |
} | |
#[derive(Debug)] | |
pub enum DaoError<'a, T> | |
where | |
T: TryFrom<&'a Value>, | |
<T as TryFrom<&'a Value>>::Error: Debug, | |
{ | |
UglyConvertError(<T as TryFrom<&'a Value>>::Error), // this is ugly | |
ConvertError(ConvertError), // why can't it be wrapped into this? | |
NoSuchValueError(String), | |
} | |
#[derive(Debug)] | |
pub enum ConvertError { | |
NotSupported(String), | |
} | |
#[derive(Debug, PartialEq)] | |
pub struct Dao<'a>(BTreeMap<&'a str, Value>); | |
impl<'a> Dao<'a> { | |
pub fn new() -> Self { | |
Dao(BTreeMap::new()) | |
} | |
pub fn insert<V>(&mut self, s: &'a str, v: V) | |
where | |
V: Into<Value>, | |
{ | |
self.0.insert(s, v.into()); | |
} | |
pub fn get<T>(&'a self, s: &str) -> Result<T, DaoError<T>> | |
where | |
T: TryFrom<&'a Value>, | |
<T as TryFrom<&'a Value>>::Error: Debug, | |
{ | |
let value: Option<&'a Value> = self.0.get(s); | |
match value { | |
Some(v) => TryFrom::try_from(v).map_err(|e| DaoError::UglyConvertError(e)), | |
None => Err(DaoError::NoSuchValueError(s.into())), | |
} | |
} | |
/* | |
//I wanted a simpler Error signature, but this is erroneous | |
pub fn simpl_get<T>(&'a self, s: &str) -> Result<T, DaoError<T>> | |
where | |
T: TryFrom<&'a Value> | |
{ | |
let value: Option<&'a Value> = self.0.get(s); | |
match value { | |
Some(v) => TryFrom::try_from(v).map_err(|e| DaoError::ConvertError(e)), | |
None => Err(DaoError::NoSuchValueError(s.into())), | |
} | |
} | |
*/ | |
} | |
impl<'a> TryFrom<&'a Value> for f64 { | |
type Error = ConvertError; | |
fn try_from(value: &'a Value) -> Result<Self, Self::Error> { | |
match *value { | |
Value::Double(v) => Ok(v), | |
_ => Err(ConvertError::NotSupported("can not convert to f64".into())), | |
} | |
} | |
} | |
impl<'a> TryFrom<&'a Value> for String { | |
type Error = ConvertError; | |
fn try_from(value: &'a Value) -> Result<Self, Self::Error> { | |
match *value { | |
Value::Text(ref v) => Ok(v.to_owned()), | |
_ => Err(ConvertError::NotSupported( | |
"can not convert to String".into(), | |
)), | |
} | |
} | |
} | |
impl From<f64> for Value { | |
fn from(f: f64) -> Self { | |
Value::Double(f) | |
} | |
} | |
impl<'a> From<&'a str> for Value { | |
fn from(f: &str) -> Self { | |
Value::Text(f.to_owned()) | |
} | |
} | |
fn main() { | |
let mut dao = Dao::new(); | |
dao.insert("life", 42.0f64); | |
dao.insert("lemons", "lemonade"); | |
let life: Result<f64, _> = dao.get("life"); | |
println!("life: {:#?}", life); | |
assert!(life.is_ok()); | |
if let Ok(life) = life { | |
assert_eq!(life, 42.0f64); | |
}; | |
let lemons: Result<String, _> = dao.get("lemons"); | |
println!("lemons?: {:#?}", lemons); | |
assert!(lemons.is_ok()); | |
if let Ok(lemons) = lemons { | |
assert_eq!(lemons, "lemonade"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment