Created
October 6, 2017 17:53
-
-
Save anonymous/d42e84f3ce6202c3a327206bf69d8d2c 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::Error: Debug, | |
{ | |
UglyConvertError(T::Error), | |
ConvertError(ConvertError), | |
NoSuchValueError(String), | |
} | |
impl<'a, T> std::ops::Deref for DaoError<'a, T> | |
where | |
T: TryFrom<&'a Value>, | |
T::Error: Debug{ | |
type Target = ConvertError; | |
fn deref(&self) -> &Self::Target { | |
match *self{ | |
DaoError::ConvertError(ref e) => e, | |
_ => panic!("only for converterror") | |
} | |
} | |
} | |
#[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::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())), | |
} | |
} | |
} | |
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