Skip to content

Instantly share code, notes, and snippets.

@highlyunavailable
Created April 25, 2016 18:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save highlyunavailable/0dab6e17bbace8fd10fa7c2e2f121d27 to your computer and use it in GitHub Desktop.
Save highlyunavailable/0dab6e17bbace8fd10fa7c2e2f121d27 to your computer and use it in GitHub Desktop.
extern crate toml;
use decode::Decoder;
use message::Message;
use std::error::Error;
#[derive(Default)]
pub struct JsonDecoder {
value: i64,
}
impl Decoder for JsonDecoder {
fn decode(&self, data: Vec<u8>) -> Result<Message, Box<Error>> {
println!{"decoder value: {}", self.value}
Ok(Message::new())
}
}
impl JsonDecoder {
pub fn new(c: toml::Value) -> Result<Box<Decoder>, Box<Error>> {
match c {
toml::Value::Integer(x) => Ok(Box::new(JsonDecoder { value: x })),
_ => unimplemented!{},
}
}
}
extern crate toml;
use message::Message;
use std::error::Error;
use std::collections::HashMap;
pub mod json;
pub trait Decoder: Send + Sync {
fn decode(&self, data: Vec<u8>) -> Result<Message, Box<Error>>;
}
pub type BindFunc = fn(toml::Value) -> Result<Box<Decoder>, Box<Error>>;
pub struct Registry<'a> {
binders: HashMap<String, BindFunc>,
decoders: HashMap<String, Box<Decoder + 'a>>,
defaults: HashMap<String, Box<Decoder + 'a>>,
}
impl<'a> Registry<'a> {
pub fn new() -> Registry<'a> {
Registry {
binders: HashMap::new(),
decoders: HashMap::new(),
defaults: HashMap::new(),
}
}
pub fn register_binder(&mut self, name: String, b: BindFunc) {
self.binders.insert(name, b);
()
}
pub fn register_defaultdecoder(&mut self, name: String, d: Box<Decoder>) {
self.defaults.insert(name, d);
()
}
pub fn register_customdecoder(&mut self, name: String, d: Box<Decoder>) {
self.decoders.insert(name, d);
()
}
pub fn get_binder(&'a self, id: String) -> Option<&BindFunc> {
self.binders.get(&id)
}
pub fn default(&'a self, id: String) -> Option<&Box<Decoder + 'a>> {
self.defaults.get(&id)
}
pub fn get(&'a self, id: String) -> Option<&Box<Decoder + 'a>> {
self.decoders.get(&id)
}
}
// lazy_static!{ pub static ref REGISTRY: Registry<'static> = {let mut r = Registry::new(); r};}
#[macro_use]
extern crate lazy_static;
extern crate toml;
mod message;
mod decode;
fn main() {
let mut r = decode::Registry::new();
reg_custom(&mut r);
reg_default(&mut r);
use_reg(&r);
use_default(&r);
}
fn reg_custom(r: &mut decode::Registry) {
r.register_binder("json".to_string(), decode::json::JsonDecoder::new);
let bound = r.get_binder("json".to_string()).unwrap()(toml::Value::Integer(6)).unwrap();
r.register_customdecoder("json".to_string(), bound);
}
fn reg_default(r: &mut decode::Registry) {
let d: decode::json::JsonDecoder = Default::default();
r.register_defaultdecoder("json".to_string(), Box::new(d));
}
fn use_reg(r: &decode::Registry) {
let decoder = r.get("json".to_string()).unwrap();
decoder.decode(vec![]);
}
fn use_default(r: &decode::Registry) {
let decoder = r.default("json".to_string()).unwrap();
decoder.decode(vec![]);
}
extern crate time;
use std::collections::BTreeMap;
// Mostly taken whole-cloth from http://amznlabs.github.io/ion-docs/spec.html - may be a good idea to
// clean up portions later.
pub enum MessageValue {
Null,
Bool(bool),
Int(i64),
Float(f64),
Decimal(f64), /* http://speleotrove.com/decimal/decarith.html - shouldn't really be a float, should be a base 10 float. */
Timestamp(time::Tm),
String(String),
Symbol(String),
Blob(Vec<u8>),
Clob(String),
Struct(BTreeMap<String, MessageValue>),
List(Vec<MessageValue>),
SExp(Vec<MessageValue>),
}
pub struct Message(BTreeMap<String, MessageValue>);
impl Message {
pub fn new() -> Message {
return Message(BTreeMap::new());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment