1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
use rustc_serialize::{Decodable, Encodable}; use rustc_serialize::json::{self, Json}; use super::{Serialized, Unserialized, UnserializedIr}; use value::{Value, ConvIr, FromValue}; use error::{Error, Result as MyResult}; use std::convert::From; use std::str::{from_utf8, from_utf8_unchecked}; impl From<Json> for Value { fn from(x: Json) -> Value { Value::Bytes(json::encode(&x).unwrap().into()) } } impl<T: Encodable> From<Serialized<T>> for Value { fn from(x: Serialized<T>) -> Value { Value::Bytes(json::encode(&x.0).unwrap().into()) } } impl<T: Decodable> ConvIr<Unserialized<T>> for UnserializedIr<T> { fn new(v: Value) -> MyResult<UnserializedIr<T>> { let (output, bytes) = { let bytes = match v { Value::Bytes(bytes) => { match from_utf8(&*bytes) { Ok(_) => bytes, Err(_) => return Err(Error::FromValueError(Value::Bytes(bytes))), } } v => return Err(Error::FromValueError(v)), }; let output = { match json::decode(unsafe { from_utf8_unchecked(&*bytes) }) { Ok(output) => output, Err(_) => return Err(Error::FromValueError(Value::Bytes(bytes))), } }; (output, bytes) }; Ok(UnserializedIr { bytes: bytes, output: Unserialized(output), }) } fn commit(self) -> Unserialized<T> { self.output } fn rollback(self) -> Value { Value::Bytes(self.bytes) } } impl<T: Decodable> FromValue for Unserialized<T> { type Intermediate = UnserializedIr<T>; } #[derive(Debug)] pub struct JsonIr { bytes: Vec<u8>, output: Json, } impl ConvIr<Json> for JsonIr { fn new(v: Value) -> MyResult<JsonIr> { let (output, bytes) = { let bytes = match v { Value::Bytes(bytes) => { match from_utf8(&*bytes) { Ok(_) => bytes, Err(_) => return Err(Error::FromValueError(Value::Bytes(bytes))), } } v => return Err(Error::FromValueError(v)), }; let output = { match Json::from_str(unsafe { from_utf8_unchecked(&*bytes) }) { Ok(output) => output, Err(_) => return Err(Error::FromValueError(Value::Bytes(bytes))), } }; (output, bytes) }; Ok(JsonIr { bytes: bytes, output: output, }) } fn commit(self) -> Json { self.output } fn rollback(self) -> Value { Value::Bytes(self.bytes) } } impl FromValue for Json { type Intermediate = JsonIr; }