提交 d1a83e69 编写于 作者: E Erick Tryzelaar

std: add Encoder::emit_map and Decoder::read_map

上级 ed62f6df
......@@ -402,6 +402,21 @@ fn read_option<T>(&self, f: &fn(bool) -> T) -> T {
}
}
}
fn read_map<T>(&self, _f: &fn(uint) -> T) -> T {
debug!("read_map()");
fail!(~"read_map is unimplemented");
}
fn read_map_elt_key<T>(&self, idx: uint, _f: &fn() -> T) -> T {
debug!("read_map_elt_key(idx=%u)", idx);
fail!(~"read_map_elt_val is unimplemented");
}
fn read_map_elt_val<T>(&self, idx: uint, _f: &fn() -> T) -> T {
debug!("read_map_elt_val(idx=%u)", idx);
fail!(~"read_map_elt_val is unimplemented");
}
}
}
......@@ -654,6 +669,18 @@ fn emit_option_none(&self) {
fn emit_option_some(&self, f: &fn()) {
self.emit_enum_variant("Some", 1, 1, f)
}
fn emit_map(&self, _len: uint, _f: &fn()) {
fail!(~"emit_map is unimplemented");
}
fn emit_map_elt_key(&self, _idx: uint, _f: &fn()) {
fail!(~"emit_map_elt_key is unimplemented");
}
fn emit_map_elt_val(&self, _idx: uint, _f: &fn()) {
fail!(~"emit_map_elt_val is unimplemented");
}
}
}
......
......@@ -466,8 +466,8 @@ pub trait FromWriter {
fn from_writer(w: @Writer) -> Self;
}
impl<'self> FromReader for json::Decoder<'self> {
fn from_reader(r: @Reader) -> json::Decoder<'self> {
impl FromReader for json::Decoder {
fn from_reader(r: @Reader) -> json::Decoder {
match json::from_reader(r) {
Ok(json) => {
json::Decoder(json)
......
......@@ -156,6 +156,22 @@ fn emit_field(&self, name: &str, idx: uint, f: &fn()) {
fn emit_option(&self, f: &fn()) { f(); }
fn emit_option_none(&self) { self.emit_nil(); }
fn emit_option_some(&self, f: &fn()) { f(); }
fn emit_map(&self, _len: uint, f: &fn()) {
self.wr.write_char('{');
f();
self.wr.write_char('}');
}
fn emit_map_elt_key(&self, idx: uint, f: &fn()) {
if idx != 0 { self.wr.write_char(','); }
f()
}
fn emit_map_elt_val(&self, _idx: uint, f: &fn()) {
self.wr.write_char(':');
f()
}
}
pub struct PrettyEncoder {
......@@ -276,6 +292,34 @@ fn emit_field(&self, name: &str, idx: uint, f: &fn()) {
fn emit_option(&self, f: &fn()) { f(); }
fn emit_option_none(&self) { self.emit_nil(); }
fn emit_option_some(&self, f: &fn()) { f(); }
fn emit_map(&self, len: uint, f: &fn()) {
if len == 0 {
self.wr.write_str("{}");
} else {
self.wr.write_char('{');
self.indent += 2;
f();
self.wr.write_char('\n');
self.indent -= 2;
self.wr.write_str(spaces(self.indent));
self.wr.write_char('}');
}
}
fn emit_map_elt_key(&self, idx: uint, f: &fn()) {
if idx == 0 {
self.wr.write_char('\n');
} else {
self.wr.write_str(",\n");
}
self.wr.write_str(spaces(self.indent));
f();
}
fn emit_map_elt_val(&self, _idx: uint, f: &fn()) {
self.wr.write_str(": ");
f();
}
}
impl<E: serialize::Encoder> serialize::Encodable<E> for Json {
......@@ -285,17 +329,7 @@ fn encode(&self, e: &E) {
String(ref v) => v.encode(e),
Boolean(v) => v.encode(e),
List(ref v) => v.encode(e),
Object(ref v) => {
do e.emit_struct("Object", v.len())|| {
let mut idx = 0;
for v.each |&(key, value)| {
do e.emit_field(*key, idx) {
value.encode(e);
}
idx += 1;
}
}
},
Object(ref v) => v.encode(e),
Null => e.emit_nil(),
}
}
......@@ -702,37 +736,20 @@ pub fn from_str(s: &str) -> Result<Json, Error> {
}
}
pub struct Decoder<'self> {
priv json: Json,
priv mut stack: ~[&'self Json],
pub struct Decoder {
priv mut stack: ~[Json],
}
pub fn Decoder(json: Json) -> Decoder {
Decoder { json: json, stack: ~[] }
}
priv impl<'self> Decoder<'self> {
fn peek(&self) -> &'self Json {
if vec::uniq_len(&const self.stack) == 0 {
self.stack.push(&self.json);
}
self.stack[vec::uniq_len(&const self.stack) - 1]
}
fn pop(&self) -> &'self Json {
if vec::uniq_len(&const self.stack) == 0 {
self.stack.push(&self.json);
}
self.stack.pop()
}
Decoder { stack: ~[json] }
}
impl<'self> serialize::Decoder for Decoder<'self> {
impl serialize::Decoder for Decoder {
fn read_nil(&self) -> () {
debug!("read_nil");
match *self.pop() {
match self.stack.pop() {
Null => (),
_ => fail!(~"not a null")
value => fail!(fmt!("not a null: %?", value))
}
}
......@@ -750,9 +767,9 @@ fn read_int(&self) -> int { self.read_float() as int }
fn read_bool(&self) -> bool {
debug!("read_bool");
match *self.pop() {
match self.stack.pop() {
Boolean(b) => b,
_ => fail!(~"not a boolean")
value => fail!(fmt!("not a boolean: %?", value))
}
}
......@@ -760,9 +777,9 @@ fn read_f64(&self) -> f64 { self.read_float() as f64 }
fn read_f32(&self) -> f32 { self.read_float() as f32 }
fn read_float(&self) -> float {
debug!("read_float");
match *self.pop() {
match self.stack.pop() {
Number(f) => f,
_ => fail!(~"not a number")
value => fail!(fmt!("not a number: %?", value))
}
}
......@@ -775,13 +792,12 @@ fn read_char(&self) -> char {
fn read_str(&self) -> ~str {
debug!("read_str");
match *self.pop() {
String(ref s) => copy *s,
ref json => fail!(fmt!("not a string: %?", *json))
match self.stack.pop() {
String(s) => s,
json => fail!(fmt!("not a string: %?", json))
}
}
fn read_enum<T>(&self, name: &str, f: &fn() -> T) -> T {
debug!("read_enum(%s)", name);
f()
......@@ -790,9 +806,9 @@ fn read_enum<T>(&self, name: &str, f: &fn() -> T) -> T {
#[cfg(stage0)]
fn read_enum_variant<T>(&self, f: &fn(uint) -> T) -> T {
debug!("read_enum_variant()");
let idx = match *self.peek() {
Null => 0,
_ => 1,
let idx = match self.stack.pop() {
Null => { self.stack.push(Null); 0 },
value => { self.stack.push(value); 1 },
};
f(idx)
}
......@@ -802,12 +818,20 @@ fn read_enum_variant<T>(&self, f: &fn(uint) -> T) -> T {
#[cfg(stage3)]
fn read_enum_variant<T>(&self, names: &[&str], f: &fn(uint) -> T) -> T {
debug!("read_enum_variant(names=%?)", names);
let name = match *self.peek() {
String(ref s) => s,
List([String(ref s), .. _]) => s,
let name = match self.stack.pop() {
String(s) => s,
List(list) => {
do vec::consume_reverse(list) |_i, v| {
self.stack.push(v);
}
match self.stack.pop() {
String(s) => s,
value => fail!(fmt!("invalid variant name: %?", value)),
}
}
ref json => fail!(fmt!("invalid variant: %?", *json)),
};
let idx = match vec::position(names, |n| str::eq_slice(*n, *name)) {
let idx = match vec::position(names, |n| str::eq_slice(*n, name)) {
Some(idx) => idx,
None => fail!(fmt!("Unknown variant name: %?", name)),
};
......@@ -816,73 +840,90 @@ fn read_enum_variant<T>(&self, names: &[&str], f: &fn(uint) -> T) -> T {
fn read_enum_variant_arg<T>(&self, idx: uint, f: &fn() -> T) -> T {
debug!("read_enum_variant_arg(idx=%u)", idx);
match *self.peek() {
List(ref list) => {
self.stack.push(&list[idx + 1]);
f()
}
ref json => fail!(fmt!("not a list: %?", json)),
}
f()
}
fn read_seq<T>(&self, f: &fn(uint) -> T) -> T {
debug!("read_seq()");
let len = match *self.peek() {
List(ref list) => list.len(),
let len = match self.stack.pop() {
List(list) => {
let len = list.len();
do vec::consume_reverse(list) |_i, v| {
self.stack.push(v);
}
len
}
_ => fail!(~"not a list"),
};
let res = f(len);
self.pop();
self.stack.pop();
res
}
fn read_seq_elt<T>(&self, idx: uint, f: &fn() -> T) -> T {
debug!("read_seq_elt(idx=%u)", idx);
match *self.peek() {
List(ref list) => {
self.stack.push(&list[idx]);
f()
}
_ => fail!(~"not a list"),
}
f()
}
fn read_struct<T>(&self, _name: &str, _len: uint, f: &fn() -> T) -> T {
debug!("read_struct()");
fn read_struct<T>(&self, name: &str, len: uint, f: &fn() -> T) -> T {
debug!("read_struct(name=%s, len=%u)", name, len);
let value = f();
self.pop();
self.stack.pop();
value
}
fn read_field<T>(&self, name: &str, idx: uint, f: &fn() -> T) -> T {
debug!("read_field(%s, idx=%u)", name, idx);
let top = self.peek();
match *top {
Object(ref obj) => {
match obj.find(&name.to_owned()) {
match self.stack.pop() {
Object(obj) => {
let mut obj = obj;
let value = match obj.pop(&name.to_owned()) {
None => fail!(fmt!("no such field: %s", name)),
Some(json) => {
self.stack.push(json);
f()
}
}
};
self.stack.push(Object(obj));
value
}
Number(_) => fail!(~"num"),
String(_) => fail!(~"str"),
Boolean(_) => fail!(~"bool"),
List(_) => fail!(fmt!("list: %?", top)),
Null => fail!(~"null"),
//_ => fail!(fmt!("not an object: %?", *top))
value => fail!(fmt!("not an object: %?", value))
}
}
fn read_option<T>(&self, f: &fn(bool) -> T) -> T {
match *self.peek() {
Null => { self.pop(); f(false) }
_ => f(true),
match self.stack.pop() {
Null => f(false),
value => { self.stack.push(value); f(true) }
}
}
fn read_map<T>(&self, f: &fn(uint) -> T) -> T {
debug!("read_map()");
let len = match self.stack.pop() {
Object(obj) => {
let mut obj = obj;
let len = obj.len();
do obj.consume |key, value| {
self.stack.push(value);
self.stack.push(String(key));
}
len
}
json => fail!(fmt!("not an object: %?", json)),
};
f(len)
}
fn read_map_elt_key<T>(&self, idx: uint, f: &fn() -> T) -> T {
debug!("read_map_elt_key(idx=%u)", idx);
f()
}
fn read_map_elt_val<T>(&self, idx: uint, f: &fn() -> T) -> T {
debug!("read_map_elt_val(idx=%u)", idx);
f()
}
}
impl Eq for Json {
......@@ -1251,7 +1292,7 @@ fn test_write_object() {
#[test]
fn test_write_object_pretty() {
assert_eq!(to_pretty_str(&mk_object(~[])), ~"{\n}");
assert_eq!(to_pretty_str(&mk_object(~[])), ~"{}");
assert_eq!(
to_pretty_str(&mk_object(~[(~"a", Boolean(true))])),
~"\
......@@ -1630,6 +1671,16 @@ fn test_read_enum_multiple_args() {
assert_eq!(value, Frog(~"Henry", 349));
}
#[test]
fn test_read_map() {
let s = ~"{\"a\": \"Dog\", \"b\": [\"Frog\", \"Henry\", 349]}";
let decoder = Decoder(from_str(s).unwrap());
let map: LinearMap<~str, Animal> = Decodable::decode(&decoder);
assert_eq!(map.find(&~"a"), Some(Dog));
assert_eq!(map.find(&~"b"), Some(Frog(~"Henry", 349)));
}
#[test]
fn test_multiline_errors() {
assert_eq!(from_str(~"{\n \"foo\":\n \"bar\""),
......
......@@ -16,9 +16,8 @@
#[forbid(non_camel_case_types)];
use core::at_vec;
use core::prelude::*;
use core::vec;
use core::hashmap::linear::LinearMap;
pub trait Encoder {
// Primitive types:
......@@ -56,6 +55,10 @@ pub trait Encoder {
fn emit_option(&self, f: &fn());
fn emit_option_none(&self);
fn emit_option_some(&self, f: &fn());
fn emit_map(&self, len: uint, f: &fn());
fn emit_map_elt_key(&self, idx: uint, f: &fn());
fn emit_map_elt_val(&self, idx: uint, f: &fn());
}
pub trait Decoder {
......@@ -96,6 +99,10 @@ pub trait Decoder {
// Specialized types:
fn read_option<T>(&self, f: &fn(bool) -> T) -> T;
fn read_map<T>(&self, f: &fn(uint) -> T) -> T;
fn read_map_elt_key<T>(&self, idx: uint, f: &fn() -> T) -> T;
fn read_map_elt_val<T>(&self, idx: uint, f: &fn() -> T) -> T;
}
pub trait Encodable<S:Encoder> {
......@@ -529,6 +536,58 @@ fn decode(d: &D)
}
}
impl<
E: Encoder,
K: Encodable<E> + Hash + IterBytes + Eq,
V: Encodable<E>
> Encodable<E> for LinearMap<K, V> {
fn encode(&self, e: &E) {
do e.emit_map(self.len()) {
let mut i = 0;
for self.each |&(key, val)| {
e.emit_map_elt_key(i, || key.encode(e));
e.emit_map_elt_val(i, || val.encode(e));
i += 1;
}
}
}
}
impl<
D: Decoder,
K: Decodable<D> + Hash + IterBytes + Eq,
V: Decodable<D>
> Decodable<D> for LinearMap<K, V> {
#[cfg(stage0)]
fn decode(d: &D) -> LinearMap<K, V> {
do d.read_map |len| {
let mut map = LinearMap::new();
map.reserve_at_least(len);
for uint::range(0, len) |i| {
let key = d.read_map_elt_key(i, || Decodable::decode(d));
let val = d.read_map_elt_val(i, || Decodable::decode(d));
map.insert(key, val);
}
map
}
}
#[cfg(stage1)]
#[cfg(stage2)]
#[cfg(stage3)]
fn decode(d: &D) -> LinearMap<K, V> {
do d.read_map |len| {
let mut map = LinearMap::with_capacity(len);
for uint::range(0, len) |i| {
let key = d.read_map_elt_key(i, || Decodable::decode(d));
let val = d.read_map_elt_val(i, || Decodable::decode(d));
map.insert(key, val);
}
map
}
}
}
// ___________________________________________________________________________
// Helper routines
//
......
......@@ -137,7 +137,11 @@ fn new(kind: &str, name: &str) -> WorkKey {
}
}
type WorkMap = LinearMap<WorkKey, ~str>;
struct WorkMap(LinearMap<WorkKey, ~str>);
impl WorkMap {
fn new() -> WorkMap { WorkMap(LinearMap::new()) }
}
impl<S:Encoder> Encodable<S> for WorkMap {
fn encode(&self, s: &S) {
......@@ -153,7 +157,7 @@ fn encode(&self, s: &S) {
impl<D:Decoder> Decodable<D> for WorkMap {
fn decode(d: &D) -> WorkMap {
let v : ~[(WorkKey,~str)] = Decodable::decode(d);
let mut w = LinearMap::new();
let mut w = WorkMap::new();
for v.each |&(k, v)| {
w.insert(copy k, copy v);
}
......@@ -235,7 +239,7 @@ fn json_encode<T:Encodable<json::Encoder>>(t: &T) -> ~str {
}
// FIXME(#5121)
fn json_decode<T:Decodable<json::Decoder<'static>>>(s: &str) -> T {
fn json_decode<T:Decodable<json::Decoder>>(s: &str) -> T {
do io::with_str_reader(s) |rdr| {
let j = result::unwrap(json::from_reader(rdr));
Decodable::decode(&json::Decoder(j))
......@@ -260,18 +264,25 @@ pub impl Context {
fn new(db: @Mut<Database>,
lg: @Mut<Logger>,
cfg: @json::Object) -> Context {
Context{db: db, logger: lg, cfg: cfg, freshness: LinearMap::new()}
Context {
db: db,
logger: lg,
cfg: cfg,
freshness: LinearMap::new()
}
}
fn prep<T:Owned +
Encodable<json::Encoder> +
Decodable<json::Decoder<'static>>>( // FIXME(#5121)
Decodable<json::Decoder>>( // FIXME(#5121)
@self,
fn_name:&str,
blk: &fn(@Mut<Prep>)->Work<T>) -> Work<T> {
let p = @Mut(Prep {ctxt: self,
fn_name: fn_name.to_owned(),
declared_inputs: LinearMap::new()});
let p = @Mut(Prep {
ctxt: self,
fn_name: fn_name.to_owned(),
declared_inputs: WorkMap::new()
});
blk(p)
}
}
......@@ -283,7 +294,7 @@ trait TPrep {
fn all_fresh(&self, cat:&str, map:&WorkMap) -> bool;
fn exec<T:Owned +
Encodable<json::Encoder> +
Decodable<json::Decoder<'static>>>( // FIXME(#5121)
Decodable<json::Decoder>>( // FIXME(#5121)
&self, blk: ~fn(&Exec) -> T) -> Work<T>;
}
......@@ -324,7 +335,7 @@ fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool {
fn exec<T:Owned +
Encodable<json::Encoder> +
Decodable<json::Decoder<'static>>>( // FIXME(#5121)
Decodable<json::Decoder>>( // FIXME(#5121)
&self, blk: ~fn(&Exec) -> T) -> Work<T> {
let mut bo = Some(blk);
......@@ -349,8 +360,10 @@ fn exec<T:Owned +
let blk = blk.unwrap();
let chan = Cell(chan);
do task::spawn || {
let exe = Exec{discovered_inputs: LinearMap::new(),
discovered_outputs: LinearMap::new()};
let exe = Exec {
discovered_inputs: WorkMap::new(),
discovered_outputs: WorkMap::new(),
};
let chan = chan.take();
let v = blk(&exe);
send_one(chan, (exe, v));
......@@ -365,7 +378,7 @@ fn exec<T:Owned +
pub impl<T:Owned +
Encodable<json::Encoder> +
Decodable<json::Decoder<'static>>> Work<T> { // FIXME(#5121)
Decodable<json::Decoder>> Work<T> { // FIXME(#5121)
fn new(p: @Mut<Prep>, e: Either<T,PortOne<(Exec,T)>>) -> Work<T> {
Work { prep: p, res: Some(e) }
}
......@@ -374,7 +387,7 @@ fn new(p: @Mut<Prep>, e: Either<T,PortOne<(Exec,T)>>) -> Work<T> {
// FIXME (#3724): movable self. This should be in impl Work.
fn unwrap<T:Owned +
Encodable<json::Encoder> +
Decodable<json::Decoder<'static>>>( // FIXME(#5121)
Decodable<json::Decoder>>( // FIXME(#5121)
w: Work<T>) -> T {
let mut ww = w;
let mut s = None;
......
......@@ -1280,6 +1280,16 @@ fn emit_option_some(&self, f: &fn()) {
self.add_to_log(CallToEmitOptionSome);
f();
}
fn read_map<T>(&self, f: &fn(uint) -> T) -> T {
self.add_unknown_to_log(); f(0);
}
fn read_map_elt_key<T>(&self, idx: uint, f: &fn() -> T) -> T {
self.add_unknown_to_log(); f();
}
fn read_map_elt_val<T>(&self, idx: uint, f: &fn() -> T) -> T {
self.add_unknown_to_log(); f();
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册