diff options
| author | Simon BD <simon@server> | 2012-10-22 18:33:41 -0500 |
|---|---|---|
| committer | Simon BD <simon@server> | 2012-10-22 18:33:41 -0500 |
| commit | cc0f2c6bb26ba38d3487a396fa8625e938af6820 (patch) | |
| tree | 6c2063df35144c5477b0adc9e49933d71224dc2a /src/libstd | |
| parent | 9aec7a3e85c5b07923eab05d3ebe9d031bf258f3 (diff) | |
| parent | 9ee5fff4f16cfc3390bd69abbb46b0a68521667c (diff) | |
Merge remote-tracking branch 'original/incoming' into incoming
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/arc.rs | 49 | ||||
| -rw-r--r-- | src/libstd/arena.rs | 4 | ||||
| -rw-r--r-- | src/libstd/bitv.rs | 6 | ||||
| -rw-r--r-- | src/libstd/cell.rs | 2 | ||||
| -rw-r--r-- | src/libstd/comm.rs | 8 | ||||
| -rw-r--r-- | src/libstd/ebml.rs | 394 | ||||
| -rw-r--r-- | src/libstd/ebml2.rs | 644 | ||||
| -rw-r--r-- | src/libstd/getopts.rs | 412 | ||||
| -rw-r--r-- | src/libstd/json.rs | 103 | ||||
| -rw-r--r-- | src/libstd/map.rs | 5 | ||||
| -rw-r--r-- | src/libstd/net_ip.rs | 31 | ||||
| -rw-r--r-- | src/libstd/net_tcp.rs | 96 | ||||
| -rw-r--r-- | src/libstd/net_url.rs | 32 | ||||
| -rw-r--r-- | src/libstd/prettyprint.rs | 168 | ||||
| -rw-r--r-- | src/libstd/prettyprint2.rs | 176 | ||||
| -rw-r--r-- | src/libstd/serialization.rs | 1087 | ||||
| -rw-r--r-- | src/libstd/serialization2.rs | 563 | ||||
| -rw-r--r-- | src/libstd/sort.rs | 2 | ||||
| -rw-r--r-- | src/libstd/std.rc | 7 | ||||
| -rw-r--r-- | src/libstd/sync.rs | 80 | ||||
| -rw-r--r-- | src/libstd/test.rs | 10 | ||||
| -rw-r--r-- | src/libstd/time.rs | 3 | ||||
| -rw-r--r-- | src/libstd/timer.rs | 4 | ||||
| -rw-r--r-- | src/libstd/treemap.rs | 56 | ||||
| -rw-r--r-- | src/libstd/uv_ll.rs | 28 |
25 files changed, 2015 insertions, 1955 deletions
diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index addabb2ddb9..9c793028a52 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -124,7 +124,7 @@ pub fn mutex_arc_with_condvars<T: Send>(user_data: T, num_condvars: uint) -> MutexARC<T> { let data = MutexARCInner { lock: mutex_with_condvars(num_condvars), - failed: false, data: user_data }; + failed: false, data: move user_data }; MutexARC { x: unsafe { shared_mutable_state(move data) } } } @@ -190,7 +190,7 @@ impl<T: Send> &MutexARC<T> { * * Will additionally fail if another task has failed while accessing the arc. */ -// FIXME(#2585) make this a by-move method on the arc +// FIXME(#3724) make this a by-move method on the arc pub fn unwrap_mutex_arc<T: Send>(arc: MutexARC<T>) -> T { let MutexARC { x: x } <- arc; let inner = unsafe { unwrap_shared_mutable_state(move x) }; @@ -258,7 +258,7 @@ pub fn rw_arc_with_condvars<T: Const Send>(user_data: T, num_condvars: uint) -> RWARC<T> { let data = RWARCInner { lock: rwlock_with_condvars(num_condvars), - failed: false, data: user_data }; + failed: false, data: move user_data }; RWARC { x: unsafe { shared_mutable_state(move data) }, cant_nest: () } } @@ -368,7 +368,7 @@ impl<T: Const Send> &RWARC<T> { * Will additionally fail if another task has failed while accessing the arc * in write mode. */ -// FIXME(#2585) make this a by-move method on the arc +// FIXME(#3724) make this a by-move method on the arc pub fn unwrap_rw_arc<T: Const Send>(arc: RWARC<T>) -> T { let RWARC { x: x, _ } <- arc; let inner = unsafe { unwrap_shared_mutable_state(move x) }; @@ -448,7 +448,7 @@ mod tests { let (c, p) = pipes::stream(); - do task::spawn() { + do task::spawn() |move c| { let p = pipes::PortSet(); c.send(p.chan()); @@ -471,8 +471,8 @@ mod tests { let arc = ~MutexARC(false); let arc2 = ~arc.clone(); let (c,p) = pipes::oneshot(); - let (c,p) = (~mut Some(c), ~mut Some(p)); - do task::spawn { + let (c,p) = (~mut Some(move c), ~mut Some(move p)); + do task::spawn |move arc2, move p| { // wait until parent gets in pipes::recv_one(option::swap_unwrap(p)); do arc2.access_cond |state, cond| { @@ -494,7 +494,7 @@ mod tests { let arc2 = ~arc.clone(); let (c,p) = pipes::stream(); - do task::spawn_unlinked { + do task::spawn_unlinked |move arc2, move p| { let _ = p.recv(); do arc2.access_cond |one, cond| { cond.signal(); @@ -513,7 +513,7 @@ mod tests { fn test_mutex_arc_poison() { let arc = ~MutexARC(1); let arc2 = ~arc.clone(); - do task::try { + do task::try |move arc2| { do arc2.access |one| { assert *one == 2; } @@ -527,21 +527,21 @@ mod tests { let arc = MutexARC(1); let arc2 = ~(&arc).clone(); let (c,p) = pipes::stream(); - do task::spawn { + do task::spawn |move c, move arc2| { do arc2.access |one| { c.send(()); assert *one == 2; } } let _ = p.recv(); - let one = unwrap_mutex_arc(arc); + let one = unwrap_mutex_arc(move arc); assert one == 1; } #[test] #[should_fail] #[ignore(cfg(windows))] fn test_rw_arc_poison_wr() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try { + do task::try |move arc2| { do arc2.write |one| { assert *one == 2; } @@ -554,7 +554,7 @@ mod tests { fn test_rw_arc_poison_ww() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try { + do task::try |move arc2| { do arc2.write |one| { assert *one == 2; } @@ -567,7 +567,7 @@ mod tests { fn test_rw_arc_poison_dw() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try { + do task::try |move arc2| { do arc2.write_downgrade |write_mode| { do (&write_mode).write |one| { assert *one == 2; @@ -582,7 +582,7 @@ mod tests { fn test_rw_arc_no_poison_rr() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try { + do task::try |move arc2| { do arc2.read |one| { assert *one == 2; } @@ -595,7 +595,7 @@ mod tests { fn test_rw_arc_no_poison_rw() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try { + do task::try |move arc2| { do arc2.read |one| { assert *one == 2; } @@ -608,9 +608,9 @@ mod tests { fn test_rw_arc_no_poison_dr() { let arc = ~RWARC(1); let arc2 = ~arc.clone(); - do task::try { + do task::try |move arc2| { do arc2.write_downgrade |write_mode| { - let read_mode = arc2.downgrade(write_mode); + let read_mode = arc2.downgrade(move write_mode); do (&read_mode).read |one| { assert *one == 2; } @@ -626,7 +626,7 @@ mod tests { let arc2 = ~arc.clone(); let (c,p) = pipes::stream(); - do task::spawn { + do task::spawn |move arc2, move c| { do arc2.write |num| { for 10.times { let tmp = *num; @@ -642,7 +642,8 @@ mod tests { let mut children = ~[]; for 5.times { let arc3 = ~arc.clone(); - do task::task().future_result(|+r| children.push(r)).spawn { + do task::task().future_result(|+r| children.push(move r)).spawn + |move arc3| { do arc3.read |num| { assert *num >= 0; } @@ -670,9 +671,9 @@ mod tests { let mut reader_convos = ~[]; for 10.times { let ((rc1,rp1),(rc2,rp2)) = (pipes::stream(),pipes::stream()); - reader_convos.push((rc1,rp2)); + reader_convos.push((move rc1, move rp2)); let arcn = ~arc.clone(); - do task::spawn { + do task::spawn |move rp1, move rc2, move arcn| { rp1.recv(); // wait for downgrader to give go-ahead do arcn.read |state| { assert *state == 31337; @@ -684,7 +685,7 @@ mod tests { // Writer task let arc2 = ~arc.clone(); let ((wc1,wp1),(wc2,wp2)) = (pipes::stream(),pipes::stream()); - do task::spawn { + do task::spawn |move arc2, move wc2, move wp1| { wp1.recv(); do arc2.write_cond |state, cond| { assert *state == 0; @@ -717,7 +718,7 @@ mod tests { } } } - let read_mode = arc.downgrade(write_mode); + let read_mode = arc.downgrade(move write_mode); do (&read_mode).read |state| { // complete handshake with other readers for vec::each(reader_convos) |x| { diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index 6a2ac88f714..9f40794b28a 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -244,7 +244,7 @@ fn test_arena_destructors() { do arena.alloc { @i }; // Allocate something with funny size and alignment, to keep // things interesting. - do arena.alloc { [0u8, 1u8, 2u8]/3 }; + do arena.alloc { [0u8, 1u8, 2u8] }; } } @@ -258,7 +258,7 @@ fn test_arena_destructors_fail() { do arena.alloc { @i }; // Allocate something with funny size and alignment, to keep // things interesting. - do arena.alloc { [0u8, 1u8, 2u8]/3 }; + do arena.alloc { [0u8, 1u8, 2u8] }; } // Now, fail while allocating do arena.alloc::<@int> { diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index 91af4a3d653..2b8e9b6bbd9 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -96,7 +96,7 @@ struct BigBitv { } fn BigBitv(storage: ~[mut uint]) -> BigBitv { - BigBitv {storage: storage} + BigBitv {storage: move storage} } /** @@ -223,7 +223,7 @@ pub fn Bitv (nbits: uint, init: bool) -> Bitv { let s = to_mut(from_elem(nelems, elem)); Big(~BigBitv(move s)) }; - Bitv {rep: rep, nbits: nbits} + Bitv {rep: move rep, nbits: nbits} } priv impl Bitv { @@ -301,7 +301,7 @@ impl Bitv { let st = to_mut(from_elem(self.nbits / uint_bits + 1, 0)); let len = st.len(); for uint::range(0, len) |i| { st[i] = b.storage[i]; }; - Bitv{nbits: self.nbits, rep: Big(~BigBitv{storage: st})} + Bitv{nbits: self.nbits, rep: Big(~BigBitv{storage: move st})} } } } diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs index c888957728a..4f79bf2b316 100644 --- a/src/libstd/cell.rs +++ b/src/libstd/cell.rs @@ -57,7 +57,7 @@ fn test_basic() { let value = value_cell.take(); assert value == ~10; assert value_cell.is_empty(); - value_cell.put_back(value); + value_cell.put_back(move value); assert !value_cell.is_empty(); } diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index 1a897a2c2fa..e604b87b2af 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -52,12 +52,12 @@ pub fn DuplexStream<T: Send, U: Send>() let (c2, p1) = pipes::stream(); let (c1, p2) = pipes::stream(); (DuplexStream { - chan: c1, - port: p1 + chan: move c1, + port: move p1 }, DuplexStream { - chan: c2, - port: p2 + chan: move c2, + port: move p2 }) } diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 3df5a70a0c1..79e491e309b 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -1,21 +1,35 @@ #[forbid(deprecated_mode)]; +use serialization; + // Simple Extensible Binary Markup Language (ebml) reader and writer on a // cursor model. See the specification here: // http://www.matroska.org/technical/specs/rfc/index.html -use core::Option; -use option::{Some, None}; -type EbmlTag = {id: uint, size: uint}; +struct EbmlTag { + id: uint, + size: uint, +} -type EbmlState = {ebml_tag: EbmlTag, tag_pos: uint, data_pos: uint}; +struct EbmlState { + ebml_tag: EbmlTag, + tag_pos: uint, + data_pos: uint, +} // FIXME (#2739): When we have module renaming, make "reader" and "writer" // separate modules within this file. // ebml reading -pub type Doc = {data: @~[u8], start: uint, end: uint}; +struct Doc { + data: @~[u8], + start: uint, + end: uint, +} -type TaggedDoc = {tag: uint, doc: Doc}; +struct TaggedDoc { + tag: uint, + doc: Doc, +} impl Doc: ops::Index<uint,Doc> { pure fn index(tag: uint) -> Doc { @@ -49,15 +63,17 @@ fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} { } pub fn Doc(data: @~[u8]) -> Doc { - return {data: data, start: 0u, end: vec::len::<u8>(*data)}; + Doc { data: data, start: 0u, end: vec::len::<u8>(*data) } } pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc { let elt_tag = vuint_at(*data, start); let elt_size = vuint_at(*data, elt_tag.next); let end = elt_size.next + elt_size.val; - return {tag: elt_tag.val, - doc: {data: data, start: elt_size.next, end: end}}; + TaggedDoc { + tag: elt_tag.val, + doc: Doc { data: data, start: elt_size.next, end: end } + } } pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> { @@ -67,19 +83,15 @@ pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> { let elt_size = vuint_at(*d.data, elt_tag.next); pos = elt_size.next + elt_size.val; if elt_tag.val == tg { - return Some::<Doc>({ - data: d.data, - start: elt_size.next, - end: pos - }); + return Some(Doc { data: d.data, start: elt_size.next, end: pos }); } } - return None::<Doc>; + None } pub fn get_doc(d: Doc, tg: uint) -> Doc { match maybe_get_doc(d, tg) { - Some(d) => return d, + Some(d) => d, None => { error!("failed to find block with tag %u", tg); fail; @@ -93,7 +105,8 @@ pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) { let elt_tag = vuint_at(*d.data, pos); let elt_size = vuint_at(*d.data, elt_tag.next); pos = elt_size.next + elt_size.val; - if !it(elt_tag.val, {data: d.data, start: elt_size.next, end: pos}) { + let doc = Doc { data: d.data, start: elt_size.next, end: pos }; + if !it(elt_tag.val, doc) { break; } } @@ -106,7 +119,8 @@ pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { let elt_size = vuint_at(*d.data, elt_tag.next); pos = elt_size.next + elt_size.val; if elt_tag.val == tg { - if !it({data: d.data, start: elt_size.next, end: pos}) { + let doc = Doc { data: d.data, start: elt_size.next, end: pos }; + if !it(doc) { break; } } @@ -116,29 +130,29 @@ pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::<u8>(*d.data, d.start, d.end) } pub fn with_doc_data<T>(d: Doc, f: fn(x: &[u8]) -> T) -> T { - return f(vec::view(*d.data, d.start, d.end)); + f(vec::view(*d.data, d.start, d.end)) } -pub fn doc_as_str(d: Doc) -> ~str { return str::from_bytes(doc_data(d)); } +pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) } pub fn doc_as_u8(d: Doc) -> u8 { assert d.end == d.start + 1u; - return (*d.data)[d.start]; + (*d.data)[d.start] } pub fn doc_as_u16(d: Doc) -> u16 { assert d.end == d.start + 2u; - return io::u64_from_be_bytes(*d.data, d.start, 2u) as u16; + io::u64_from_be_bytes(*d.data, d.start, 2u) as u16 } pub fn doc_as_u32(d: Doc) -> u32 { assert d.end == d.start + 4u; - return io::u64_from_be_bytes(*d.data, d.start, 4u) as u32; + io::u64_from_be_bytes(*d.data, d.start, 4u) as u32 } pub fn doc_as_u64(d: Doc) -> u64 { assert d.end == d.start + 8u; - return io::u64_from_be_bytes(*d.data, d.start, 8u); + io::u64_from_be_bytes(*d.data, d.start, 8u) } pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } @@ -147,10 +161,9 @@ pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } // ebml writing -type Writer_ = {writer: io::Writer, mut size_positions: ~[uint]}; - -pub enum Writer { - Writer_(Writer_) +struct Serializer { + writer: io::Writer, + priv mut size_positions: ~[uint], } fn write_sized_vuint(w: io::Writer, n: uint, size: uint) { @@ -173,13 +186,13 @@ fn write_vuint(w: io::Writer, n: uint) { fail fmt!("vint to write too big: %?", n); } -pub fn Writer(w: io::Writer) -> Writer { +pub fn Serializer(w: io::Writer) -> Serializer { let size_positions: ~[uint] = ~[]; - return Writer_({writer: w, mut size_positions: size_positions}); + Serializer { writer: w, mut size_positions: size_positions } } // FIXME (#2741): Provide a function to write the standard ebml header. -impl Writer { +impl Serializer { fn start_tag(tag_id: uint) { debug!("Start tag %u", tag_id); @@ -295,12 +308,7 @@ enum EbmlSerializerTag { EsLabel // Used only when debugging } -trait SerializerPriv { - fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint); - fn _emit_label(label: &str); -} - -impl ebml::Writer: SerializerPriv { +priv impl Serializer { // used internally to emit things like the vector length and so on fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint) { assert v <= 0xFFFF_FFFF_u; @@ -318,89 +326,123 @@ impl ebml::Writer: SerializerPriv { } } -impl ebml::Writer { - fn emit_opaque(f: fn()) { +impl Serializer { + fn emit_opaque(&self, f: fn()) { do self.wr_tag(EsOpaque as uint) { f() } } } -impl ebml::Writer: serialization::Serializer { - fn emit_nil() {} +impl Serializer: serialization::Serializer { + fn emit_nil(&self) {} - fn emit_uint(v: uint) { self.wr_tagged_u64(EsUint as uint, v as u64); } - fn emit_u64(v: u64) { self.wr_tagged_u64(EsU64 as uint, v); } - fn emit_u32(v: u32) { self.wr_tagged_u32(EsU32 as uint, v); } - fn emit_u16(v: u16) { self.wr_tagged_u16(EsU16 as uint, v); } - fn emit_u8(v: u8) { self.wr_tagged_u8 (EsU8 as uint, v); } + fn emit_uint(&self, v: uint) { + self.wr_tagged_u64(EsUint as uint, v as u64); + } + fn emit_u64(&self, v: u64) { self.wr_tagged_u64(EsU64 as uint, v); } + fn emit_u32(&self, v: u32) { self.wr_tagged_u32(EsU32 as uint, v); } + fn emit_u16(&self, v: u16) { self.wr_tagged_u16(EsU16 as uint, v); } + fn emit_u8(&self, v: u8) { self.wr_tagged_u8 (EsU8 as uint, v); } - fn emit_int(v: int) { self.wr_tagged_i64(EsInt as uint, v as i64); } - fn emit_i64(v: i64) { self.wr_tagged_i64(EsI64 as uint, v); } - fn emit_i32(v: i32) { self.wr_tagged_i32(EsI32 as uint, v); } - fn emit_i16(v: i16) { self.wr_tagged_i16(EsI16 as uint, v); } - fn emit_i8(v: i8) { self.wr_tagged_i8 (EsI8 as uint, v); } + fn emit_int(&self, v: int) { + self.wr_tagged_i64(EsInt as uint, v as i64); + } + fn emit_i64(&self, v: i64) { self.wr_tagged_i64(EsI64 as uint, v); } + fn emit_i32(&self, v: i32) { self.wr_tagged_i32(EsI32 as uint, v); } + fn emit_i16(&self, v: i16) { self.wr_tagged_i16(EsI16 as uint, v); } + fn emit_i8(&self, v: i8) { self.wr_tagged_i8 (EsI8 as uint, v); } - fn emit_bool(v: bool) { self.wr_tagged_u8(EsBool as uint, v as u8) } + fn emit_bool(&self, v: bool) { + self.wr_tagged_u8(EsBool as uint, v as u8) + } // FIXME (#2742): implement these - fn emit_f64(_v: f64) { fail ~"Unimplemented: serializing an f64"; } - fn emit_f32(_v: f32) { fail ~"Unimplemented: serializing an f32"; } - fn emit_float(_v: float) { fail ~"Unimplemented: serializing a float"; } + fn emit_f64(&self, _v: f64) { fail ~"Unimplemented: serializing an f64"; } + fn emit_f32(&self, _v: f32) { fail ~"Unimplemented: serializing an f32"; } + fn emit_float(&self, _v: float) { + fail ~"Unimplemented: serializing a float"; + } + + fn emit_char(&self, _v: char) { + fail ~"Unimplemented: serializing a char"; + } - fn emit_str(v: &str) { self.wr_tagged_str(EsStr as uint, v) } + fn emit_borrowed_str(&self, v: &str) { + self.wr_tagged_str(EsStr as uint, v) + } - fn emit_enum(name: &str, f: fn()) { + fn emit_owned_str(&self, v: &str) { + self.emit_borrowed_str(v) + } + + fn emit_managed_str(&self, v: &str) { + self.emit_borrowed_str(v) + } + + fn emit_borrowed(&self, f: fn()) { f() } + fn emit_owned(&self, f: fn()) { f() } + fn emit_managed(&self, f: fn()) { f() } + + fn emit_enum(&self, name: &str, f: fn()) { self._emit_label(name); self.wr_tag(EsEnum as uint, f) } - fn emit_enum_variant(_v_name: &str, v_id: uint, _cnt: uint, f: fn()) { + fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint, + f: fn()) { self._emit_tagged_uint(EsEnumVid, v_id); self.wr_tag(EsEnumBody as uint, f) } - fn emit_enum_variant_arg(_idx: uint, f: fn()) { f() } + fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() } - fn emit_vec(len: uint, f: fn()) { + fn emit_borrowed_vec(&self, len: uint, f: fn()) { do self.wr_tag(EsVec as uint) { self._emit_tagged_uint(EsVecLen, len); f() } } - fn emit_vec_elt(_idx: uint, f: fn()) { + fn emit_owned_vec(&self, len: uint, f: fn()) { + self.emit_borrowed_vec(len, f) + } + + fn emit_managed_vec(&self, len: uint, f: fn()) { + self.emit_borrowed_vec(len, f) + } + + fn emit_vec_elt(&self, _idx: uint, f: fn()) { self.wr_tag(EsVecElt as uint, f) } - fn emit_box(f: fn()) { f() } - fn emit_uniq(f: fn()) { f() } - fn emit_rec(f: fn()) { f() } - fn emit_rec_field(f_name: &str, _f_idx: uint, f: fn()) { - self._emit_label(f_name); + fn emit_rec(&self, f: fn()) { f() } + fn emit_struct(&self, _name: &str, f: fn()) { f() } + fn emit_field(&self, name: &str, _idx: uint, f: fn()) { + self._emit_label(name); f() } - fn emit_tup(_sz: uint, f: fn()) { f() } - fn emit_tup_elt(_idx: uint, f: fn()) { f() } -} -type EbmlDeserializer_ = {mut parent: ebml::Doc, - mut pos: uint}; + fn emit_tup(&self, _len: uint, f: fn()) { f() } + fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() } +} -pub enum EbmlDeserializer { - EbmlDeserializer_(EbmlDeserializer_) +struct Deserializer { + priv mut parent: Doc, + priv mut pos: uint, } -pub fn ebml_deserializer(d: ebml::Doc) -> EbmlDeserializer { - EbmlDeserializer_({mut parent: d, mut pos: d.start}) +pub fn Deserializer(d: Doc) -> Deserializer { + Deserializer { mut parent: d, mut pos: d.start } } -priv impl EbmlDeserializer { +priv impl Deserializer { fn _check_label(lbl: &str) { if self.pos < self.parent.end { - let {tag: r_tag, doc: r_doc} = - ebml::doc_at(self.parent.data, self.pos); + let TaggedDoc { tag: r_tag, doc: r_doc } = + doc_at(self.parent.data, self.pos); + if r_tag == (EsLabel as uint) { self.pos = r_doc.end; - let str = ebml::doc_as_str(r_doc); + let str = doc_as_str(r_doc); if lbl != str { fail fmt!("Expected label %s but found %s", lbl, str); } @@ -408,13 +450,13 @@ priv impl EbmlDeserializer { } } - fn next_doc(exp_tag: EbmlSerializerTag) -> ebml::Doc { + fn next_doc(exp_tag: EbmlSerializerTag) -> Doc { debug!(". next_doc(exp_tag=%?)", exp_tag); if self.pos >= self.parent.end { fail ~"no more documents in current node!"; } - let {tag: r_tag, doc: r_doc} = - ebml::doc_at(self.parent.data, self.pos); + let TaggedDoc { tag: r_tag, doc: r_doc } = + doc_at(self.parent.data, self.pos); debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?", copy self.parent.start, copy self.parent.end, copy self.pos, r_tag, r_doc.start, r_doc.end); @@ -427,10 +469,10 @@ priv impl EbmlDeserializer { r_doc.end, self.parent.end); } self.pos = r_doc.end; - return r_doc; + r_doc } - fn push_doc<T>(d: ebml::Doc, f: fn() -> T) -> T{ + fn push_doc<T>(d: Doc, f: fn() -> T) -> T{ let old_parent = self.parent; let old_pos = self.pos; self.parent = d; @@ -442,63 +484,76 @@ priv impl EbmlDeserializer { } fn _next_uint(exp_tag: EbmlSerializerTag) -> uint { - let r = ebml::doc_as_u32(self.next_doc(exp_tag)); + let r = doc_as_u32(self.next_doc(exp_tag)); debug!("_next_uint exp_tag=%? result=%?", exp_tag, r); - return r as uint; + r as uint } } -impl EbmlDeserializer { - fn read_opaque<R>(op: fn(ebml::Doc) -> R) -> R { +impl Deserializer { + fn read_opaque<R>(&self, op: fn(Doc) -> R) -> R { do self.push_doc(self.next_doc(EsOpaque)) { op(copy self.parent) } } } -impl EbmlDeserializer: serialization::Deserializer { - fn read_nil() -> () { () } +impl Deserializer: serialization::Deserializer { + fn read_nil(&self) -> () { () } - fn read_u64() -> u64 { ebml::doc_as_u64(self.next_doc(EsU64)) } - fn read_u32() -> u32 { ebml::doc_as_u32(self.next_doc(EsU32)) } - fn read_u16() -> u16 { ebml::doc_as_u16(self.next_doc(EsU16)) } - fn read_u8 () -> u8 { ebml::doc_as_u8 (self.next_doc(EsU8 )) } - fn read_uint() -> uint { - let v = ebml::doc_as_u64(self.next_doc(EsUint)); + fn read_u64(&self) -> u64 { doc_as_u64(self.next_doc(EsU64)) } + fn read_u32(&self) -> u32 { doc_as_u32(self.next_doc(EsU32)) } + fn read_u16(&self) -> u16 { doc_as_u16(self.next_doc(EsU16)) } + fn read_u8 (&self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) } + fn read_uint(&self) -> uint { + let v = doc_as_u64(self.next_doc(EsUint)); if v > (core::uint::max_value as u64) { fail fmt!("uint %? too large for this architecture", v); } - return v as uint; + v as uint } - fn read_i64() -> i64 { ebml::doc_as_u64(self.next_doc(EsI64)) as i64 } - fn read_i32() -> i32 { ebml::doc_as_u32(self.next_doc(EsI32)) as i32 } - fn read_i16() -> i16 { ebml::doc_as_u16(self.next_doc(EsI16)) as i16 } - fn read_i8 () -> i8 { ebml::doc_as_u8 (self.next_doc(EsI8 )) as i8 } - fn read_int() -> int { - let v = ebml::doc_as_u64(self.next_doc(EsInt)) as i64; + fn read_i64(&self) -> i64 { doc_as_u64(self.next_doc(EsI64)) as i64 } + fn read_i32(&self) -> i32 { doc_as_u32(self.next_doc(EsI32)) as i32 } + fn read_i16(&self) -> i16 { doc_as_u16(self.next_doc(EsI16)) as i16 } + fn read_i8 (&self) -> i8 { doc_as_u8 (self.next_doc(EsI8 )) as i8 } + fn read_int(&self) -> int { + let v = doc_as_u64(self.next_doc(EsInt)) as i64; if v > (int::max_value as i64) || v < (int::min_value as i64) { fail fmt!("int %? out of range for this architecture", v); } - return v as int; + v as int } - fn read_bool() -> bool { ebml::doc_as_u8(self.next_doc(EsBool)) as bool } + fn read_bool(&self) -> bool { doc_as_u8(self.next_doc(EsBool)) as bool } + + fn read_f64(&self) -> f64 { fail ~"read_f64()"; } + fn read_f32(&self) -> f32 { fail ~"read_f32()"; } + fn read_float(&self) -> float { fail ~"read_float()"; } - fn read_f64() -> f64 { fail ~"read_f64()"; } - fn read_f32() -> f32 { fail ~"read_f32()"; } - fn read_float() -> float { fail ~"read_float()"; } + fn read_char(&self) -> char { fail ~"read_char()"; } - fn read_str() -> ~str { ebml::doc_as_str(self.next_doc(EsStr)) } + fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) } + fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; } // Compound types: - fn read_enum<T>(name: &str, f: fn() -> T) -> T { + fn read_owned<T>(&self, f: fn() -> T) -> T { + debug!("read_owned()"); + f() + } + + fn read_managed<T>(&self, f: fn() -> T) -> T { + debug!("read_managed()"); + f() + } + + fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T { debug!("read_enum(%s)", name); self._check_label(name); self.push_doc(self.next_doc(EsEnum), f) } - fn read_enum_variant<T>(f: fn(uint) -> T) -> T { + fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T { debug!("read_enum_variant()"); let idx = self._next_uint(EsEnumVid); debug!(" idx=%u", idx); @@ -507,13 +562,13 @@ impl EbmlDeserializer: serialization::Deserializer { } } - fn read_enum_variant_arg<T>(idx: uint, f: fn() -> T) -> T { + fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T { debug!("read_enum_variant_arg(idx=%u)", idx); f() } - fn read_vec<T>(f: fn(uint) -> T) -> T { - debug!("read_vec()"); + fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T { + debug!("read_owned_vec()"); do self.push_doc(self.next_doc(EsVec)) { let len = self._next_uint(EsVecLen); debug!(" len=%u", len); @@ -521,104 +576,69 @@ impl EbmlDeserializer: serialization::Deserializer { } } - fn read_vec_elt<T>(idx: uint, f: fn() -> T) -> T { - debug!("read_vec_elt(idx=%u)", idx); - self.push_doc(self.next_doc(EsVecElt), f) + fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T { + debug!("read_managed_vec()"); + do self.push_doc(self.next_doc(EsVec)) { + let len = self._next_uint(EsVecLen); + debug!(" len=%u", len); + f(len) + } } - fn read_box<T>(f: fn() -> T) -> T { - debug!("read_box()"); - f() + fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T { + debug!("read_vec_elt(idx=%u)", idx); + self.push_doc(self.next_doc(EsVecElt), f) } - fn read_uniq<T>(f: fn() -> T) -> T { - debug!("read_uniq()"); + fn read_rec<T>(&self, f: fn() -> T) -> T { + debug!("read_rec()"); f() } - fn read_rec<T>(f: fn() -> T) -> T { - debug!("read_rec()"); + fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T { + debug!("read_struct(name=%s)", name); f() } - fn read_rec_field<T>(f_name: &str, f_idx: uint, f: fn() -> T) -> T { - debug!("read_rec_field(%s, idx=%u)", f_name, f_idx); - self._check_label(f_name); + fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T { + debug!("read_field(name=%s, idx=%u)", name, idx); + self._check_label(name); f() } - fn read_tup<T>(sz: uint, f: fn() -> T) -> T { - debug!("read_tup(sz=%u)", sz); + fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T { + debug!("read_tup(len=%u)", len); f() } - fn read_tup_elt<T>(idx: uint, f: fn() -> T) -> T { + fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T { debug!("read_tup_elt(idx=%u)", idx); f() } } - // ___________________________________________________________________________ // Testing -#[test] -fn test_option_int() { - fn serialize_1<S: serialization::Serializer>(s: &S, v: int) { - s.emit_i64(v as i64); - } - - fn serialize_0<S: serialization::Serializer>(s: &S, v: Option<int>) { - do s.emit_enum(~"core::option::t") { - match v { - None => s.emit_enum_variant( - ~"core::option::None", 0u, 0u, || { } ), - Some(v0) => { - do s.emit_enum_variant(~"core::option::some", 1u, 1u) { - s.emit_enum_variant_arg(0u, || serialize_1(s, v0)); - } - } - } +#[cfg(test)] +mod tests { + #[test] + fn test_option_int() { + fn test_v(v: Option<int>) { + debug!("v == %?", v); + let bytes = do io::with_bytes_writer |wr| { + let ebml_w = Serializer(wr); + v.serialize(&ebml_w) + }; + let ebml_doc = Doc(@bytes); + let deser = Deserializer(ebml_doc); + let v1 = serialization::deserialize(&deser); + debug!("v1 == %?", v1); + assert v == v1; } - } - fn deserialize_1<S: serialization::Deserializer>(s: &S) -> int { - s.read_i64() as int - } - - fn deserialize_0<S: serialization::Deserializer>(s: &S) -> Option<int> { - do s.read_enum(~"core::option::t") { - do s.read_enum_variant |i| { - match i { - 0 => None, - 1 => { - let v0 = do s.read_enum_variant_arg(0u) { - deserialize_1(s) - }; - Some(v0) - } - _ => { - fail #fmt("deserialize_0: unexpected variant %u", i); - } - } - } - } + test_v(Some(22)); + test_v(None); + test_v(Some(3)); } - - fn test_v(v: Option<int>) { - debug!("v == %?", v); - let bytes = do io::with_bytes_writer |wr| { - let ebml_w = ebml::Writer(wr); - serialize_0(&ebml_w, v); - }; - let ebml_doc = ebml::Doc(@bytes); - let deser = ebml_deserializer(ebml_doc); - let v1 = deserialize_0(&deser); - debug!("v1 == %?", v1); - assert v == v1; - } - - test_v(Some(22)); - test_v(None); - test_v(Some(3)); } diff --git a/src/libstd/ebml2.rs b/src/libstd/ebml2.rs deleted file mode 100644 index f88aad1ac63..00000000000 --- a/src/libstd/ebml2.rs +++ /dev/null @@ -1,644 +0,0 @@ -#[forbid(deprecated_mode)]; -use serialization2; - -// Simple Extensible Binary Markup Language (ebml) reader and writer on a -// cursor model. See the specification here: -// http://www.matroska.org/technical/specs/rfc/index.html - -struct EbmlTag { - id: uint, - size: uint, -} - -struct EbmlState { - ebml_tag: EbmlTag, - tag_pos: uint, - data_pos: uint, -} - -// FIXME (#2739): When we have module renaming, make "reader" and "writer" -// separate modules within this file. - -// ebml reading -struct Doc { - data: @~[u8], - start: uint, - end: uint, -} - -struct TaggedDoc { - tag: uint, - doc: Doc, -} - -impl Doc: ops::Index<uint,Doc> { - pure fn index(tag: uint) -> Doc { - unsafe { - get_doc(self, tag) - } - } -} - -fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} { - let a = data[start]; - if a & 0x80u8 != 0u8 { - return {val: (a & 0x7fu8) as uint, next: start + 1u}; - } - if a & 0x40u8 != 0u8 { - return {val: ((a & 0x3fu8) as uint) << 8u | - (data[start + 1u] as uint), - next: start + 2u}; - } else if a & 0x20u8 != 0u8 { - return {val: ((a & 0x1fu8) as uint) << 16u | - (data[start + 1u] as uint) << 8u | - (data[start + 2u] as uint), - next: start + 3u}; - } else if a & 0x10u8 != 0u8 { - return {val: ((a & 0x0fu8) as uint) << 24u | - (data[start + 1u] as uint) << 16u | - (data[start + 2u] as uint) << 8u | - (data[start + 3u] as uint), - next: start + 4u}; - } else { error!("vint too big"); fail; } -} - -pub fn Doc(data: @~[u8]) -> Doc { - Doc { data: data, start: 0u, end: vec::len::<u8>(*data) } -} - -pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc { - let elt_tag = vuint_at(*data, start); - let elt_size = vuint_at(*data, elt_tag.next); - let end = elt_size.next + elt_size.val; - TaggedDoc { - tag: elt_tag.val, - doc: Doc { data: data, start: elt_size.next, end: end } - } -} - -pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(*d.data, pos); - let elt_size = vuint_at(*d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - if elt_tag.val == tg { - return Some(Doc { data: d.data, start: elt_size.next, end: pos }); - } - } - None -} - -pub fn get_doc(d: Doc, tg: uint) -> Doc { - match maybe_get_doc(d, tg) { - Some(d) => d, - None => { - error!("failed to find block with tag %u", tg); - fail; - } - } -} - -pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(*d.data, pos); - let elt_size = vuint_at(*d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - let doc = Doc { data: d.data, start: elt_size.next, end: pos }; - if !it(elt_tag.val, doc) { - break; - } - } -} - -pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { - let mut pos = d.start; - while pos < d.end { - let elt_tag = vuint_at(*d.data, pos); - let elt_size = vuint_at(*d.data, elt_tag.next); - pos = elt_size.next + elt_size.val; - if elt_tag.val == tg { - let doc = Doc { data: d.data, start: elt_size.next, end: pos }; - if !it(doc) { - break; - } - } - } -} - -pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::<u8>(*d.data, d.start, d.end) } - -pub fn with_doc_data<T>(d: Doc, f: fn(x: &[u8]) -> T) -> T { - f(vec::view(*d.data, d.start, d.end)) -} - -pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) } - -pub fn doc_as_u8(d: Doc) -> u8 { - assert d.end == d.start + 1u; - (*d.data)[d.start] -} - -pub fn doc_as_u16(d: Doc) -> u16 { - assert d.end == d.start + 2u; - io::u64_from_be_bytes(*d.data, d.start, 2u) as u16 -} - -pub fn doc_as_u32(d: Doc) -> u32 { - assert d.end == d.start + 4u; - io::u64_from_be_bytes(*d.data, d.start, 4u) as u32 -} - -pub fn doc_as_u64(d: Doc) -> u64 { - assert d.end == d.start + 8u; - io::u64_from_be_bytes(*d.data, d.start, 8u) -} - -pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } -pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 } -pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } -pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } - -// ebml writing -struct Serializer { - writer: io::Writer, - priv mut size_positions: ~[uint], -} - -fn write_sized_vuint(w: io::Writer, n: uint, size: uint) { - match size { - 1u => w.write(&[0x80u8 | (n as u8)]), - 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]), - 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8, - n as u8]), - 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8, - (n >> 8_u) as u8, n as u8]), - _ => fail fmt!("vint to write too big: %?", n) - }; -} - -fn write_vuint(w: io::Writer, n: uint) { - if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; } - if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; } - if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; } - if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; } - fail fmt!("vint to write too big: %?", n); -} - -pub fn Serializer(w: io::Writer) -> Serializer { - let size_positions: ~[uint] = ~[]; - Serializer { writer: w, mut size_positions: size_positions } -} - -// FIXME (#2741): Provide a function to write the standard ebml header. -impl Serializer { - fn start_tag(tag_id: uint) { - debug!("Start tag %u", tag_id); - - // Write the enum ID: - write_vuint(self.writer, tag_id); - - // Write a placeholder four-byte size. - self.size_positions.push(self.writer.tell()); - let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8]; - self.writer.write(zeroes); - } - - fn end_tag() { - let last_size_pos = self.size_positions.pop(); - let cur_pos = self.writer.tell(); - self.writer.seek(last_size_pos as int, io::SeekSet); - let size = (cur_pos - last_size_pos - 4u); - write_sized_vuint(self.writer, size, 4u); - self.writer.seek(cur_pos as int, io::SeekSet); - - debug!("End tag (size = %u)", size); - } - - fn wr_tag(tag_id: uint, blk: fn()) { - self.start_tag(tag_id); - blk(); - self.end_tag(); - } - - fn wr_tagged_bytes(tag_id: uint, b: &[u8]) { - write_vuint(self.writer, tag_id); - write_vuint(self.writer, vec::len(b)); - self.writer.write(b); - } - - fn wr_tagged_u64(tag_id: uint, v: u64) { - do io::u64_to_be_bytes(v, 8u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_u32(tag_id: uint, v: u32) { - do io::u64_to_be_bytes(v as u64, 4u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_u16(tag_id: uint, v: u16) { - do io::u64_to_be_bytes(v as u64, 2u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_u8(tag_id: uint, v: u8) { - self.wr_tagged_bytes(tag_id, &[v]); - } - - fn wr_tagged_i64(tag_id: uint, v: i64) { - do io::u64_to_be_bytes(v as u64, 8u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_i32(tag_id: uint, v: i32) { - do io::u64_to_be_bytes(v as u64, 4u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_i16(tag_id: uint, v: i16) { - do io::u64_to_be_bytes(v as u64, 2u) |v| { - self.wr_tagged_bytes(tag_id, v); - } - } - - fn wr_tagged_i8(tag_id: uint, v: i8) { - self.wr_tagged_bytes(tag_id, &[v as u8]); - } - - fn wr_tagged_str(tag_id: uint, v: &str) { - str::byte_slice(v, |b| self.wr_tagged_bytes(tag_id, b)); - } - - fn wr_bytes(b: &[u8]) { - debug!("Write %u bytes", vec::len(b)); - self.writer.write(b); - } - - fn wr_str(s: &str) { - debug!("Write str: %?", s); - self.writer.write(str::to_bytes(s)); - } -} - -// FIXME (#2743): optionally perform "relaxations" on end_tag to more -// efficiently encode sizes; this is a fixed point iteration - -// Set to true to generate more debugging in EBML serialization. -// Totally lame approach. -const debug: bool = false; - -enum EbmlSerializerTag { - EsUint, EsU64, EsU32, EsU16, EsU8, - EsInt, EsI64, EsI32, EsI16, EsI8, - EsBool, - EsStr, - EsF64, EsF32, EsFloat, - EsEnum, EsEnumVid, EsEnumBody, - EsVec, EsVecLen, EsVecElt, - - EsOpaque, - - EsLabel // Used only when debugging -} - -priv impl Serializer { - // used internally to emit things like the vector length and so on - fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint) { - assert v <= 0xFFFF_FFFF_u; - self.wr_tagged_u32(t as uint, v as u32); - } - - fn _emit_label(label: &str) { - // There are various strings that we have access to, such as - // the name of a record field, which do not actually appear in - // the serialized EBML (normally). This is just for - // efficiency. When debugging, though, we can emit such - // labels and then they will be checked by deserializer to - // try and check failures more quickly. - if debug { self.wr_tagged_str(EsLabel as uint, label) } - } -} - -impl Serializer { - fn emit_opaque(&self, f: fn()) { - do self.wr_tag(EsOpaque as uint) { - f() - } - } -} - -impl Serializer: serialization2::Serializer { - fn emit_nil(&self) {} - - fn emit_uint(&self, v: uint) { - self.wr_tagged_u64(EsUint as uint, v as u64); - } - fn emit_u64(&self, v: u64) { self.wr_tagged_u64(EsU64 as uint, v); } - fn emit_u32(&self, v: u32) { self.wr_tagged_u32(EsU32 as uint, v); } - fn emit_u16(&self, v: u16) { self.wr_tagged_u16(EsU16 as uint, v); } - fn emit_u8(&self, v: u8) { self.wr_tagged_u8 (EsU8 as uint, v); } - - fn emit_int(&self, v: int) { - self.wr_tagged_i64(EsInt as uint, v as i64); - } - fn emit_i64(&self, v: i64) { self.wr_tagged_i64(EsI64 as uint, v); } - fn emit_i32(&self, v: i32) { self.wr_tagged_i32(EsI32 as uint, v); } - fn emit_i16(&self, v: i16) { self.wr_tagged_i16(EsI16 as uint, v); } - fn emit_i8(&self, v: i8) { self.wr_tagged_i8 (EsI8 as uint, v); } - - fn emit_bool(&self, v: bool) { - self.wr_tagged_u8(EsBool as uint, v as u8) - } - - // FIXME (#2742): implement these - fn emit_f64(&self, _v: f64) { fail ~"Unimplemented: serializing an f64"; } - fn emit_f32(&self, _v: f32) { fail ~"Unimplemented: serializing an f32"; } - fn emit_float(&self, _v: float) { - fail ~"Unimplemented: serializing a float"; - } - - fn emit_char(&self, _v: char) { - fail ~"Unimplemented: serializing a char"; - } - - fn emit_borrowed_str(&self, v: &str) { - self.wr_tagged_str(EsStr as uint, v) - } - - fn emit_owned_str(&self, v: &str) { - self.emit_borrowed_str(v) - } - - fn emit_managed_str(&self, v: &str) { - self.emit_borrowed_str(v) - } - - fn emit_borrowed(&self, f: fn()) { f() } - fn emit_owned(&self, f: fn()) { f() } - fn emit_managed(&self, f: fn()) { f() } - - fn emit_enum(&self, name: &str, f: fn()) { - self._emit_label(name); - self.wr_tag(EsEnum as uint, f) - } - fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint, - f: fn()) { - self._emit_tagged_uint(EsEnumVid, v_id); - self.wr_tag(EsEnumBody as uint, f) - } - fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() } - - fn emit_borrowed_vec(&self, len: uint, f: fn()) { - do self.wr_tag(EsVec as uint) { - self._emit_tagged_uint(EsVecLen, len); - f() - } - } - - fn emit_owned_vec(&self, len: uint, f: fn()) { - self.emit_borrowed_vec(len, f) - } - - fn emit_managed_vec(&self, len: uint, f: fn()) { - self.emit_borrowed_vec(len, f) - } - - fn emit_vec_elt(&self, _idx: uint, f: fn()) { - self.wr_tag(EsVecElt as uint, f) - } - - fn emit_rec(&self, f: fn()) { f() } - fn emit_struct(&self, _name: &str, f: fn()) { f() } - fn emit_field(&self, name: &str, _idx: uint, f: fn()) { - self._emit_label(name); - f() - } - - fn emit_tup(&self, _len: uint, f: fn()) { f() } - fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() } -} - -struct Deserializer { - priv mut parent: Doc, - priv mut pos: uint, -} - -pub fn Deserializer(d: Doc) -> Deserializer { - Deserializer { mut parent: d, mut pos: d.start } -} - -priv impl Deserializer { - fn _check_label(lbl: &str) { - if self.pos < self.parent.end { - let TaggedDoc { tag: r_tag, doc: r_doc } = - doc_at(self.parent.data, self.pos); - - if r_tag == (EsLabel as uint) { - self.pos = r_doc.end; - let str = doc_as_str(r_doc); - if lbl != str { - fail fmt!("Expected label %s but found %s", lbl, str); - } - } - } - } - - fn next_doc(exp_tag: EbmlSerializerTag) -> Doc { - debug!(". next_doc(exp_tag=%?)", exp_tag); - if self.pos >= self.parent.end { - fail ~"no more documents in current node!"; - } - let TaggedDoc { tag: r_tag, doc: r_doc } = - doc_at(self.parent.data, self.pos); - debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?", - copy self.parent.start, copy self.parent.end, - copy self.pos, r_tag, r_doc.start, r_doc.end); - if r_tag != (exp_tag as uint) { - fail fmt!("expected EMBL doc with tag %? but found tag %?", - exp_tag, r_tag); - } - if r_doc.end > self.parent.end { - fail fmt!("invalid EBML, child extends to 0x%x, parent to 0x%x", - r_doc.end, self.parent.end); - } - self.pos = r_doc.end; - r_doc - } - - fn push_doc<T>(d: Doc, f: fn() -> T) -> T{ - let old_parent = self.parent; - let old_pos = self.pos; - self.parent = d; - self.pos = d.start; - let r = f(); - self.parent = old_parent; - self.pos = old_pos; - move r - } - - fn _next_uint(exp_tag: EbmlSerializerTag) -> uint { - let r = doc_as_u32(self.next_doc(exp_tag)); - debug!("_next_uint exp_tag=%? result=%?", exp_tag, r); - r as uint - } -} - -impl Deserializer { - fn read_opaque<R>(&self, op: fn(Doc) -> R) -> R { - do self.push_doc(self.next_doc(EsOpaque)) { - op(copy self.parent) - } - } -} - -impl Deserializer: serialization2::Deserializer { - fn read_nil(&self) -> () { () } - - fn read_u64(&self) -> u64 { doc_as_u64(self.next_doc(EsU64)) } - fn read_u32(&self) -> u32 { doc_as_u32(self.next_doc(EsU32)) } - fn read_u16(&self) -> u16 { doc_as_u16(self.next_doc(EsU16)) } - fn read_u8 (&self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) } - fn read_uint(&self) -> uint { - let v = doc_as_u64(self.next_doc(EsUint)); - if v > (core::uint::max_value as u64) { - fail fmt!("uint %? too large for this architecture", v); - } - v as uint - } - - fn read_i64(&self) -> i64 { doc_as_u64(self.next_doc(EsI64)) as i64 } - fn read_i32(&self) -> i32 { doc_as_u32(self.next_doc(EsI32)) as i32 } - fn read_i16(&self) -> i16 { doc_as_u16(self.next_doc(EsI16)) as i16 } - fn read_i8 (&self) -> i8 { doc_as_u8 (self.next_doc(EsI8 )) as i8 } - fn read_int(&self) -> int { - let v = doc_as_u64(self.next_doc(EsInt)) as i64; - if v > (int::max_value as i64) || v < (int::min_value as i64) { - fail fmt!("int %? out of range for this architecture", v); - } - v as int - } - - fn read_bool(&self) -> bool { doc_as_u8(self.next_doc(EsBool)) as bool } - - fn read_f64(&self) -> f64 { fail ~"read_f64()"; } - fn read_f32(&self) -> f32 { fail ~"read_f32()"; } - fn read_float(&self) -> float { fail ~"read_float()"; } - - fn read_char(&self) -> char { fail ~"read_char()"; } - - fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) } - fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; } - - // Compound types: - fn read_owned<T>(&self, f: fn() -> T) -> T { - debug!("read_owned()"); - f() - } - - fn read_managed<T>(&self, f: fn() -> T) -> T { - debug!("read_managed()"); - f() - } - - fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T { - debug!("read_enum(%s)", name); - self._check_label(name); - self.push_doc(self.next_doc(EsEnum), f) - } - - fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T { - debug!("read_enum_variant()"); - let idx = self._next_uint(EsEnumVid); - debug!(" idx=%u", idx); - do self.push_doc(self.next_doc(EsEnumBody)) { - f(idx) - } - } - - fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T { - debug!("read_enum_variant_arg(idx=%u)", idx); - f() - } - - fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T { - debug!("read_owned_vec()"); - do self.push_doc(self.next_doc(EsVec)) { - let len = self._next_uint(EsVecLen); - debug!(" len=%u", len); - f(len) - } - } - - fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T { - debug!("read_managed_vec()"); - do self.push_doc(self.next_doc(EsVec)) { - let len = self._next_uint(EsVecLen); - debug!(" len=%u", len); - f(len) - } - } - - fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T { - debug!("read_vec_elt(idx=%u)", idx); - self.push_doc(self.next_doc(EsVecElt), f) - } - - fn read_rec<T>(&self, f: fn() -> T) -> T { - debug!("read_rec()"); - f() - } - - fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T { - debug!("read_struct(name=%s)", name); - f() - } - - fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T { - debug!("read_field(name=%s, idx=%u)", name, idx); - self._check_label(name); - f() - } - - fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T { - debug!("read_tup(len=%u)", len); - f() - } - - fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T { - debug!("read_tup_elt(idx=%u)", idx); - f() - } -} - -// ___________________________________________________________________________ -// Testing - -#[cfg(test)] -mod tests { - #[test] - fn test_option_int() { - fn test_v(v: Option<int>) { - debug!("v == %?", v); - let bytes = do io::with_bytes_writer |wr| { - let ebml_w = Serializer(wr); - v.serialize(&ebml_w) - }; - let ebml_doc = Doc(@bytes); - let deser = Deserializer(ebml_doc); - let v1 = serialization2::deserialize(&deser); - debug!("v1 == %?", v1); - assert v == v1; - } - - test_v(Some(22)); - test_v(None); - test_v(Some(3)); - } -} diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs index 6da51571e34..8d77b88aba2 100644 --- a/src/libstd/getopts.rs +++ b/src/libstd/getopts.rs @@ -82,7 +82,7 @@ pub type Opt = {name: Name, hasarg: HasArg, occur: Occur}; fn mkname(nm: &str) -> Name { let unm = str::from_slice(nm); - return if str::len(nm) == 1u { + return if nm.len() == 1u { Short(str::char_at(unm, 0u)) } else { Long(unm) }; } @@ -114,6 +114,22 @@ impl Occur : Eq { pure fn ne(other: &Occur) -> bool { !self.eq(other) } } +impl HasArg : Eq { + pure fn eq(other: &HasArg) -> bool { + (self as uint) == ((*other) as uint) + } + pure fn ne(other: &HasArg) -> bool { !self.eq(other) } +} + +impl Opt : Eq { + pure fn eq(other: &Opt) -> bool { + self.name == (*other).name && + self.hasarg == (*other).hasarg && + self.occur == (*other).occur + } + pure fn ne(other: &Opt) -> bool { !self.eq(other) } +} + /// Create an option that is required and takes an argument pub fn reqopt(name: &str) -> Opt { return {name: mkname(name), hasarg: Yes, occur: Req}; @@ -150,8 +166,29 @@ enum Optval { Val(~str), Given, } */ pub type Matches = {opts: ~[Opt], vals: ~[~[Optval]], free: ~[~str]}; +impl Optval : Eq { + pure fn eq(other: &Optval) -> bool { + match self { + Val(ref s) => match *other { Val (ref os) => s == os, + Given => false }, + Given => match *other { Val(_) => false, + Given => true } + } + } + pure fn ne(other: &Optval) -> bool { !self.eq(other) } +} + +impl Matches : Eq { + pure fn eq(other: &Matches) -> bool { + self.opts == (*other).opts && + self.vals == (*other).vals && + self.free == (*other).free + } + pure fn ne(other: &Matches) -> bool { !self.eq(other) } +} + fn is_arg(arg: &str) -> bool { - return str::len(arg) > 1u && arg[0] == '-' as u8; + return arg.len() > 1u && arg[0] == '-' as u8; } fn name_str(nm: &Name) -> ~str { @@ -177,6 +214,35 @@ pub enum Fail_ { UnexpectedArgument(~str), } +impl Fail_ : Eq { + // this whole thing should be easy to infer... + pure fn eq(other: &Fail_) -> bool { + match self { + ArgumentMissing(ref s) => { + match *other { ArgumentMissing(ref so) => s == so, + _ => false } + } + UnrecognizedOption(ref s) => { + match *other { UnrecognizedOption(ref so) => s == so, + _ => false } + } + OptionMissing(ref s) => { + match *other { OptionMissing(ref so) => s == so, + _ => false } + } + OptionDuplicated(ref s) => { + match *other { OptionDuplicated(ref so) => s == so, + _ => false } + } + UnexpectedArgument(ref s) => { + match *other { UnexpectedArgument(ref so) => s == so, + _ => false } + } + } + } + pure fn ne(other: &Fail_) -> bool { !self.eq(other) } +} + /// Convert a `fail_` enum into an error string pub fn fail_str(f: Fail_) -> ~str { return match f { @@ -220,7 +286,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe { let mut i = 0u; while i < l { let cur = args[i]; - let curlen = str::len(cur); + let curlen = cur.len(); if !is_arg(cur) { free.push(cur); } else if cur == ~"--" { @@ -444,6 +510,194 @@ impl FailType : Eq { pure fn ne(other: &FailType) -> bool { !self.eq(other) } } +/** A module which provides a way to specify descriptions and + * groups of short and long option names, together. + */ +pub mod groups { + + /** one group of options, e.g., both -h and --help, along with + * their shared description and properties + */ + pub type OptGroup = { + short_name: ~str, + long_name: ~str, + hint: ~str, + desc: ~str, + hasarg: HasArg, + occur: Occur + }; + + impl OptGroup : Eq { + pure fn eq(other: &OptGroup) -> bool { + self.short_name == (*other).short_name && + self.long_name == (*other).long_name && + self.hint == (*other).hint && + self.desc == (*other).desc && + self.hasarg == (*other).hasarg && + self.occur == (*other).occur + } + pure fn ne(other: &OptGroup) -> bool { !self.eq(other) } + } + + /// Create a long option that is required and takes an argument + pub fn reqopt(short_name: &str, long_name: &str, + desc: &str, hint: &str) -> OptGroup { + let len = short_name.len(); + assert len == 1 || len == 0; + return {short_name: str::from_slice(short_name), + long_name: str::from_slice(long_name), + hint: str::from_slice(hint), + desc: str::from_slice(desc), + hasarg: Yes, + occur: Req}; + } + + /// Create a long option that is optional and takes an argument + pub fn optopt(short_name: &str, long_name: &str, + desc: &str, hint: &str) -> OptGroup { + let len = short_name.len(); + assert len == 1 || len == 0; + return {short_name: str::from_slice(short_name), + long_name: str::from_slice(long_name), + hint: str::from_slice(hint), + desc: str::from_slice(desc), + hasarg: Yes, + occur: Optional}; + } + + /// Create a long option that is optional and does not take an argument + pub fn optflag(short_name: &str, long_name: &str, + desc: &str) -> OptGroup { + let len = short_name.len(); + assert len == 1 || len == 0; + return {short_name: str::from_slice(short_name), + long_name: str::from_slice(long_name), + hint: ~"", + desc: str::from_slice(desc), + hasarg: No, + occur: Optional}; + } + + /// Create a long option that is optional and takes an optional argument + pub fn optflagopt(short_name: &str, long_name: &str, + desc: &str, hint: &str) -> OptGroup { + let len = short_name.len(); + assert len == 1 || len == 0; + return {short_name: str::from_slice(short_name), + long_name: str::from_slice(long_name), + hint: str::from_slice(hint), + desc: str::from_slice(desc), + hasarg: Maybe, + occur: Optional}; + } + + /** + * Create a long option that is optional, takes an argument, and may occur + * multiple times + */ + pub fn optmulti(short_name: &str, long_name: &str, + desc: &str, hint: &str) -> OptGroup { + let len = short_name.len(); + assert len == 1 || len == 0; + return {short_name: str::from_slice(short_name), + long_name: str::from_slice(long_name), + hint: str::from_slice(hint), + desc: str::from_slice(desc), + hasarg: Yes, + occur: Multi}; + } + + // translate OptGroup into Opt + // (both short and long names correspond to different Opts) + pub fn long_to_short(lopt: &OptGroup) -> ~[Opt] { + match ((*lopt).short_name.len(), + (*lopt).long_name.len()) { + + (0,0) => fail ~"this long-format option was given no name", + + (0,_) => ~[{name: Long(((*lopt).long_name)), + hasarg: (*lopt).hasarg, + occur: (*lopt).occur}], + + (1,0) => ~[{name: Short(str::char_at((*lopt).short_name, 0)), + hasarg: (*lopt).hasarg, + occur: (*lopt).occur}], + + (1,_) => ~[{name: Short(str::char_at((*lopt).short_name, 0)), + hasarg: (*lopt).hasarg, + occur: (*lopt).occur}, + {name: Long(((*lopt).long_name)), + hasarg: (*lopt).hasarg, + occur: (*lopt).occur}], + + (_,_) => fail ~"something is wrong with the long-form opt" + } + } + + /* + * Parse command line args with the provided long format options + */ + pub fn getopts(args: &[~str], opts: &[OptGroup]) -> Result { + ::getopts::getopts(args, vec::flat_map(opts, long_to_short)) + } + + /** + * Derive a usage message from a set of long options + */ + pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str { + + let desc_sep = ~"\n" + str::repeat(~" ", 24); + + let rows = vec::map(opts, |optref| { + let short_name = (*optref).short_name; + let long_name = (*optref).long_name; + let hint = (*optref).hint; + let desc = (*optref).desc; + let hasarg = (*optref).hasarg; + + let mut row = str::repeat(~" ", 4); + + // short option + row += match short_name.len() { + 0 => ~"", + 1 => ~"-" + short_name + " ", + _ => fail ~"the short name should only be 1 char long", + }; + + // long option + row += match long_name.len() { + 0 => ~"", + _ => ~"--" + long_name + " ", + }; + + // arg + row += match hasarg { + No => ~"", + Yes => hint, + Maybe => ~"[" + hint + ~"]", + }; + + // here we just need to indent the start of the description + let rowlen = row.len(); + row += if rowlen < 24 { + str::repeat(~" ", 24 - rowlen) + } else { + desc_sep + }; + + // wrapped description + row += str::connect(str::split_within(desc, 54), desc_sep); + + row + }); + + return str::from_slice(brief) + + ~"\n\nOptions:\n" + + str::connect(rows, ~"\n") + + ~"\n\n"; + } +} // end groups module + #[cfg(test)] mod tests { #[legacy_exports]; @@ -943,6 +1197,158 @@ mod tests { assert opts_present(matches, ~[~"L"]); assert opts_str(matches, ~[~"L"]) == ~"foo"; } + + #[test] + fn test_groups_reqopt() { + let opt = groups::reqopt(~"b", ~"banana", ~"some bananas", ~"VAL"); + assert opt == { short_name: ~"b", + long_name: ~"banana", + hint: ~"VAL", + desc: ~"some bananas", + hasarg: Yes, + occur: Req } + } + + #[test] + fn test_groups_optopt() { + let opt = groups::optopt(~"a", ~"apple", ~"some apples", ~"VAL"); + assert opt == { short_name: ~"a", + long_name: ~"apple", + hint: ~"VAL", + desc: ~"some apples", + hasarg: Yes, + occur: Optional } + } + + #[test] + fn test_groups_optflag() { + let opt = groups::optflag(~"k", ~"kiwi", ~"some kiwis"); + assert opt == { short_name: ~"k", + long_name: ~"kiwi", + hint: ~"", + desc: ~"some kiwis", + hasarg: No, + occur: Optional } + } + + #[test] + fn test_groups_optflagopt() { + let opt = groups::optflagopt(~"p", ~"pineapple", + ~"some pineapples", ~"VAL"); + assert opt == { short_name: ~"p", + long_name: ~"pineapple", + hint: ~"VAL", + desc: ~"some pineapples", + hasarg: Maybe, + occur: Optional } + } + + #[test] + fn test_groups_optmulti() { + let opt = groups::optmulti(~"l", ~"lime", + ~"some limes", ~"VAL"); + assert opt == { short_name: ~"l", + long_name: ~"lime", + hint: ~"VAL", + desc: ~"some limes", + hasarg: Yes, + occur: Multi } + } + + #[test] + fn test_groups_long_to_short() { + let short = ~[reqopt(~"b"), reqopt(~"banana")]; + let verbose = groups::reqopt(~"b", ~"banana", + ~"some bananas", ~"VAL"); + + assert groups::long_to_short(&verbose) == short; + } + + #[test] + fn test_groups_getopts() { + let short = ~[ + reqopt(~"b"), reqopt(~"banana"), + optopt(~"a"), optopt(~"apple"), + optflag(~"k"), optflagopt(~"kiwi"), + optflagopt(~"p"), + optmulti(~"l") + ]; + + let verbose = ~[ + groups::reqopt(~"b", ~"banana", ~"Desc", ~"VAL"), + groups::optopt(~"a", ~"apple", ~"Desc", ~"VAL"), + groups::optflag(~"k", ~"kiwi", ~"Desc"), + groups::optflagopt(~"p", ~"", ~"Desc", ~"VAL"), + groups::optmulti(~"l", ~"", ~"Desc", ~"VAL"), + ]; + + let sample_args = ~[~"-k", ~"15", ~"--apple", ~"1", ~"k", + ~"-p", ~"16", ~"l", ~"35"]; + + // NOTE: we should sort before comparing + assert getopts(sample_args, short) + == groups::getopts(sample_args, verbose); + } + + #[test] + fn test_groups_usage() { + let optgroups = ~[ + groups::reqopt(~"b", ~"banana", ~"Desc", ~"VAL"), + groups::optopt(~"a", ~"012345678901234567890123456789", + ~"Desc", ~"VAL"), + groups::optflag(~"k", ~"kiwi", ~"Desc"), + groups::optflagopt(~"p", ~"", ~"Desc", ~"VAL"), + groups::optmulti(~"l", ~"", ~"Desc", ~"VAL"), + ]; + + let expected = +~"Usage: fruits + +Options: + -b --banana VAL Desc + -a --012345678901234567890123456789 VAL + Desc + -k --kiwi Desc + -p [VAL] Desc + -l VAL Desc + +"; + + let generated_usage = groups::usage(~"Usage: fruits", optgroups); + + debug!("expected: <<%s>>", expected); + debug!("generated: <<%s>>", generated_usage); + assert generated_usage == expected; + } + + #[test] + fn test_groups_usage_description_wrapping() { + // indentation should be 24 spaces + // lines wrap after 78: or rather descriptions wrap after 54 + + let optgroups = ~[ + groups::optflag(~"k", ~"kiwi", + ~"This is a long description which won't be wrapped..+.."), // 54 + groups::optflag(~"a", ~"apple", + ~"This is a long description which _will_ be wrapped..+.."), // 55 + ]; + + let expected = +~"Usage: fruits + +Options: + -k --kiwi This is a long description which won't be wrapped..+.. + -a --apple This is a long description which _will_ be + wrapped..+.. + +"; + + let usage = groups::usage(~"Usage: fruits", optgroups); + + debug!("expected: <<%s>>", expected); + debug!("generated: <<%s>>", usage); + assert usage == expected + } } // Local Variables: diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 09d00216209..5f64389e583 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -51,7 +51,7 @@ fn escape_str(s: &str) -> ~str { fn spaces(n: uint) -> ~str { let mut ss = ~""; - for n.times { str::push_str(&ss, " "); } + for n.times { str::push_str(&mut ss, " "); } return ss; } @@ -63,7 +63,7 @@ pub fn Serializer(wr: io::Writer) -> Serializer { Serializer { wr: wr } } -pub impl Serializer: serialization2::Serializer { +pub impl Serializer: serialization::Serializer { fn emit_nil(&self) { self.wr.write_str("null") } fn emit_uint(&self, v: uint) { self.emit_float(v as float); } @@ -167,7 +167,7 @@ pub fn PrettySerializer(wr: io::Writer) -> PrettySerializer { PrettySerializer { wr: wr, indent: 0 } } -pub impl PrettySerializer: serialization2::Serializer { +pub impl PrettySerializer: serialization::Serializer { fn emit_nil(&self) { self.wr.write_str("null") } fn emit_uint(&self, v: uint) { self.emit_float(v as float); } @@ -273,8 +273,36 @@ pub impl PrettySerializer: serialization2::Serializer { } } -pub impl Json: serialization2::Serializable { - fn serialize<S: serialization2::Serializer>(&self, s: &S) { +#[cfg(stage0)] +pub impl Json: serialization::Serializable { + fn serialize<S: serialization::Serializer>(&self, s: &S) { + match *self { + Number(v) => v.serialize(s), + String(ref v) => v.serialize(s), + Boolean(v) => v.serialize(s), + List(v) => v.serialize(s), + Object(ref v) => { + do s.emit_rec || { + let mut idx = 0; + for v.each |key, value| { + do s.emit_field(*key, idx) { + value.serialize(s); + } + idx += 1; + } + } + }, + Null => s.emit_nil(), + } + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +pub impl< + S: serialization::Serializer +> Json: serialization::Serializable<S> { + fn serialize(&self, s: &S) { match *self { Number(v) => v.serialize(s), String(ref v) => v.serialize(s), @@ -302,7 +330,8 @@ pub fn to_writer(wr: io::Writer, json: &Json) { } /// Serializes a json value into a string -pub fn to_str(json: &Json) -> ~str { +pub pure fn to_str(json: &Json) -> ~str unsafe { + // ugh, should be safe io::with_str_writer(|wr| to_writer(wr, json)) } @@ -328,8 +357,8 @@ pub fn Parser(rdr: io::Reader) -> Parser { Parser { rdr: rdr, ch: rdr.read_char(), - line: 1u, - col: 1u, + line: 1, + col: 1, } } @@ -341,7 +370,7 @@ pub impl Parser { self.parse_whitespace(); // Make sure there is no trailing characters. if self.eof() { - Ok(value) + Ok(move value) } else { self.error(~"trailing characters") } @@ -546,14 +575,14 @@ priv impl Parser { if (escape) { match self.ch { - '"' => str::push_char(&res, '"'), - '\\' => str::push_char(&res, '\\'), - '/' => str::push_char(&res, '/'), - 'b' => str::push_char(&res, '\x08'), - 'f' => str::push_char(&res, '\x0c'), - 'n' => str::push_char(&res, '\n'), - 'r' => str::push_char(&res, '\r'), - 't' => str::push_char(&res, '\t'), + '"' => str::push_char(&mut res, '"'), + '\\' => str::push_char(&mut res, '\\'), + '/' => str::push_char(&mut res, '/'), + 'b' => str::push_char(&mut res, '\x08'), + 'f' => str::push_char(&mut res, '\x0c'), + 'n' => str::push_char(&mut res, '\n'), + 'r' => str::push_char(&mut res, '\r'), + 't' => str::push_char(&mut res, '\t'), 'u' => { // Parse \u1234. let mut i = 0u; @@ -582,7 +611,7 @@ priv impl Parser { ~"invalid \\u escape (not four digits)"); } - str::push_char(&res, n as char); + str::push_char(&mut res, n as char); } _ => return self.error(~"invalid escape") } @@ -594,7 +623,7 @@ priv impl Parser { self.bump(); return Ok(res); } - str::push_char(&res, self.ch); + str::push_char(&mut res, self.ch); } } @@ -609,12 +638,12 @@ priv impl Parser { if self.ch == ']' { self.bump(); - return Ok(List(values)); + return Ok(List(move values)); } loop { match move self.parse_value() { - Ok(move v) => values.push(v), + Ok(move v) => values.push(move v), Err(move e) => return Err(e) } @@ -625,7 +654,7 @@ priv impl Parser { match self.ch { ',' => self.bump(), - ']' => { self.bump(); return Ok(List(values)); } + ']' => { self.bump(); return Ok(List(move values)); } _ => return self.error(~"expected `,` or `]`") } }; @@ -639,7 +668,7 @@ priv impl Parser { if self.ch == '}' { self.bump(); - return Ok(Object(values)); + return Ok(Object(move values)); } while !self.eof() { @@ -663,14 +692,14 @@ priv impl Parser { self.bump(); match move self.parse_value() { - Ok(move value) => { values.insert(key, value); } + Ok(move value) => { values.insert(key, move value); } Err(move e) => return Err(e) } self.parse_whitespace(); match self.ch { ',' => self.bump(), - '}' => { self.bump(); return Ok(Object(values)); } + '}' => { self.bump(); return Ok(Object(move values)); } _ => { if self.eof() { break; } return self.error(~"expected `,` or `}`"); @@ -702,7 +731,7 @@ pub struct Deserializer { pub fn Deserializer(rdr: io::Reader) -> Result<Deserializer, Error> { match move from_reader(rdr) { Ok(move json) => { - let des = Deserializer { json: json, stack: ~[] }; + let des = Deserializer { json: move json, stack: ~[] }; Ok(move des) } Err(move e) => Err(e) @@ -721,7 +750,7 @@ priv impl Deserializer { } } -pub impl Deserializer: serialization2::Deserializer { +pub impl Deserializer: serialization::Deserializer { fn read_nil(&self) -> () { debug!("read_nil"); match *self.pop() { @@ -818,7 +847,7 @@ pub impl Deserializer: serialization2::Deserializer { }; let res = f(len); self.pop(); - res + move res } fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T { @@ -829,7 +858,7 @@ pub impl Deserializer: serialization2::Deserializer { }; let res = f(len); self.pop(); - res + move res } fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T { @@ -850,14 +879,14 @@ pub impl Deserializer: serialization2::Deserializer { debug!("read_rec()"); let value = f(); self.pop(); - value + move value } fn read_struct<T>(&self, _name: &str, f: fn() -> T) -> T { debug!("read_struct()"); let value = f(); self.pop(); - value + move value } fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T { @@ -868,7 +897,7 @@ pub impl Deserializer: serialization2::Deserializer { // FIXME(#3148) This hint should not be necessary. let obj: &self/~Object = obj; - match obj.find_ref(&name.to_unique()) { + match obj.find_ref(&name.to_owned()) { None => fail fmt!("no such field: %s", name), Some(json) => { self.stack.push(json); @@ -890,7 +919,7 @@ pub impl Deserializer: serialization2::Deserializer { debug!("read_tup(len=%u)", len); let value = f(); self.pop(); - value + move value } fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T { @@ -1166,11 +1195,11 @@ impl <A: ToJson> Option<A>: ToJson { } impl Json: to_str::ToStr { - fn to_str() -> ~str { to_str(&self) } + pure fn to_str() -> ~str { to_str(&self) } } impl Error: to_str::ToStr { - fn to_str() -> ~str { + pure fn to_str() -> ~str { fmt!("%u:%u: %s", self.line, self.col, *self.msg) } } @@ -1182,11 +1211,11 @@ mod tests { for items.each |item| { match *item { - (copy key, copy value) => { d.insert(key, value); }, + (copy key, copy value) => { d.insert(key, move value); }, } }; - Object(d) + Object(move d) } #[test] diff --git a/src/libstd/map.rs b/src/libstd/map.rs index 765d40339d3..e49f1abd02b 100644 --- a/src/libstd/map.rs +++ b/src/libstd/map.rs @@ -341,7 +341,8 @@ pub mod chained { wr.write_str(~" }"); } - fn to_str() -> ~str { + pure fn to_str() -> ~str unsafe { + // Meh -- this should be safe do io::with_str_writer |wr| { self.to_writer(wr) } } } @@ -722,7 +723,7 @@ mod tests { let map = map::HashMap::<~str, ~str>(); assert (option::is_none(&map.find(key))); map.insert(key, ~"val"); - assert (option::get(&map.find(key)) == ~"val"); + assert (option::get(map.find(key)) == ~"val"); } #[test] diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs index 2d9dd5bdf4e..5d78fb19bab 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -10,8 +10,10 @@ use addrinfo = uv::ll::addrinfo; use uv_getaddrinfo_t = uv::ll::uv_getaddrinfo_t; use uv_ip4_addr = uv::ll::ip4_addr; use uv_ip4_name = uv::ll::ip4_name; +use uv_ip4_port = uv::ll::ip4_port; use uv_ip6_addr = uv::ll::ip6_addr; use uv_ip6_name = uv::ll::ip6_name; +use uv_ip6_port = uv::ll::ip6_port; use uv_getaddrinfo = uv::ll::getaddrinfo; use uv_freeaddrinfo = uv::ll::freeaddrinfo; use create_uv_getaddrinfo_t = uv::ll::getaddrinfo_t; @@ -33,11 +35,11 @@ type ParseAddrErr = { }; /** - * Convert a `ip_addr` to a str + * Convert a `IpAddr` to a str * * # Arguments * - * * ip - a `std::net::ip::ip_addr` + * * ip - a `std::net::ip::IpAddr` */ pub fn format_addr(ip: &IpAddr) -> ~str { match *ip { @@ -58,6 +60,23 @@ pub fn format_addr(ip: &IpAddr) -> ~str { } } +/** + * Get the associated port + * + * # Arguments + * * ip - a `std::net::ip::IpAddr` + */ +pub fn get_port(ip: &IpAddr) -> uint { + match *ip { + Ipv4(ref addr) => unsafe { + uv_ip4_port(addr) + }, + Ipv6(ref addr) => unsafe { + uv_ip6_port(addr) + } + } +} + /// Represents errors returned from `net::ip::get_addr()` enum IpGetAddrErr { GetAddrUnknownError @@ -128,7 +147,7 @@ pub mod v4 { */ pub fn parse_addr(ip: &str) -> IpAddr { match try_parse_addr(ip) { - result::Ok(copy addr) => addr, + result::Ok(move addr) => move addr, result::Err(ref err_data) => fail err_data.err_msg } } @@ -214,7 +233,7 @@ pub mod v6 { */ pub fn parse_addr(ip: &str) -> IpAddr { match try_parse_addr(ip) { - result::Ok(copy addr) => addr, + result::Ok(move addr) => move addr, result::Err(copy err_data) => fail err_data.err_msg } } @@ -353,7 +372,7 @@ mod test { } // note really sure how to realiably test/assert // this.. mostly just wanting to see it work, atm. - let results = result::unwrap(ga_result); + let results = result::unwrap(move ga_result); log(debug, fmt!("test_get_addr: Number of results for %s: %?", localhost_name, vec::len(results))); for vec::each(results) |r| { @@ -366,7 +385,7 @@ mod test { } // at least one result.. this is going to vary from system // to system, based on stuff like the contents of /etc/hosts - assert vec::len(results) > 0; + assert !results.is_empty(); } #[test] #[ignore(reason = "valgrind says it's leaky")] diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 249551fbb7d..942d52a3ad6 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -6,9 +6,7 @@ use ip = net_ip; use uv::iotask; use uv::iotask::IoTask; use future_spawn = future::spawn; -// FIXME #1935 -// should be able to, but can't atm, replace w/ result::{result, extensions}; -use result::*; +use result::{Result}; use libc::size_t; use io::{Reader, ReaderUtil, Writer}; use comm = core::comm; @@ -136,6 +134,10 @@ pub fn connect(input_ip: ip::IpAddr, port: uint, stream_handle_ptr: stream_handle_ptr, connect_req: uv::ll::connect_t(), write_req: uv::ll::write_t(), + ipv6: match input_ip { + ip::Ipv4(_) => { false } + ip::Ipv6(_) => { true } + }, iotask: iotask }; let socket_data_ptr = ptr::addr_of(&(*socket_data)); @@ -477,6 +479,7 @@ pub fn accept(new_conn: TcpNewConnection) stream_handle_ptr : stream_handle_ptr, connect_req : uv::ll::connect_t(), write_req : uv::ll::write_t(), + ipv6: (*server_data_ptr).ipv6, iotask : iotask }; let client_socket_data_ptr = ptr::addr_of(&(*client_socket_data)); @@ -564,7 +567,8 @@ pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint, new_connect_cb: fn~(TcpNewConnection, comm::Chan<Option<TcpErrData>>)) -> result::Result<(), TcpListenErrData> unsafe { - do listen_common(move host_ip, port, backlog, iotask, on_establish_cb) + do listen_common(move host_ip, port, backlog, iotask, + move on_establish_cb) // on_connect_cb |move new_connect_cb, handle| unsafe { let server_data_ptr = uv::ll::get_data_for_uv_handle(handle) @@ -591,6 +595,10 @@ fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint, kill_ch: kill_ch, on_connect_cb: move on_connect_cb, iotask: iotask, + ipv6: match host_ip { + ip::Ipv4(_) => { false } + ip::Ipv6(_) => { true } + }, mut active: true }; let server_data_ptr = ptr::addr_of(&server_data); @@ -747,6 +755,21 @@ impl TcpSocket { -> future::Future<result::Result<(), TcpErrData>> { write_future(&self, raw_write_data) } + pub fn get_peer_addr() -> ip::IpAddr { + unsafe { + if self.socket_data.ipv6 { + let addr = uv::ll::ip6_addr("", 0); + uv::ll::tcp_getpeername6(self.socket_data.stream_handle_ptr, + ptr::addr_of(&addr)); + ip::Ipv6(move addr) + } else { + let addr = uv::ll::ip4_addr("", 0); + uv::ll::tcp_getpeername(self.socket_data.stream_handle_ptr, + ptr::addr_of(&addr)); + ip::Ipv4(move addr) + } + } + } } /// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket` @@ -1004,6 +1027,7 @@ type TcpListenFcData = { kill_ch: comm::Chan<Option<TcpErrData>>, on_connect_cb: fn~(*uv::ll::uv_tcp_t), iotask: IoTask, + ipv6: bool, mut active: bool }; @@ -1093,7 +1117,7 @@ extern fn on_tcp_read_cb(stream: *uv::ll::uv_stream_t, log(debug, fmt!("tcp on_read_cb nread: %d", nread as int)); let reader_ch = (*socket_data_ptr).reader_ch; let buf_base = uv::ll::get_base_from_buf(buf); - let new_bytes = vec::raw::from_buf(buf_base, nread as uint); + let new_bytes = vec::from_buf(buf_base, nread as uint); core::comm::send(reader_ch, result::Ok(new_bytes)); } } @@ -1202,6 +1226,7 @@ type TcpSocketData = { stream_handle_ptr: *uv::ll::uv_tcp_t, connect_req: uv::ll::uv_connect_t, write_req: uv::ll::uv_write_t, + ipv6: bool, iotask: IoTask }; @@ -1224,6 +1249,10 @@ mod test { impl_gl_tcp_ipv4_server_and_client(); } #[test] + fn test_gl_tcp_get_peer_addr() unsafe { + impl_gl_tcp_ipv4_get_peer_addr(); + } + #[test] fn test_gl_tcp_ipv4_client_error_connection_refused() unsafe { impl_gl_tcp_ipv4_client_error_connection_refused(); } @@ -1250,6 +1279,11 @@ mod test { } #[test] #[ignore(cfg(target_os = "linux"))] + fn test_gl_tcp_get_peer_addr() unsafe { + impl_gl_tcp_ipv4_get_peer_addr(); + } + #[test] + #[ignore(cfg(target_os = "linux"))] fn test_gl_tcp_ipv4_client_error_connection_refused() unsafe { impl_gl_tcp_ipv4_client_error_connection_refused(); } @@ -1317,6 +1351,53 @@ mod test { assert str::contains(actual_req, expected_req); assert str::contains(actual_resp, expected_resp); } + fn impl_gl_tcp_ipv4_get_peer_addr() { + let hl_loop = uv::global_loop::get(); + let server_ip = ~"127.0.0.1"; + let server_port = 8887u; + let expected_resp = ~"pong"; + + let server_result_po = core::comm::Port::<~str>(); + let server_result_ch = core::comm::Chan(&server_result_po); + + let cont_po = core::comm::Port::<()>(); + let cont_ch = core::comm::Chan(&cont_po); + // server + do task::spawn_sched(task::ManualThreads(1u)) { + let actual_req = do comm::listen |server_ch| { + run_tcp_test_server( + server_ip, + server_port, + expected_resp, + server_ch, + cont_ch, + hl_loop) + }; + server_result_ch.send(actual_req); + }; + core::comm::recv(cont_po); + // client + log(debug, ~"server started, firing up client.."); + do core::comm::listen |client_ch| { + let server_ip_addr = ip::v4::parse_addr(server_ip); + let iotask = uv::global_loop::get(); + let connect_result = connect(move server_ip_addr, server_port, + iotask); + + let sock = result::unwrap(move connect_result); + + // This is what we are actually testing! + assert net::ip::format_addr(&sock.get_peer_addr()) == + ~"127.0.0.1"; + assert net::ip::get_port(&sock.get_peer_addr()) == 8887; + + // Fulfill the protocol the test server expects + let resp_bytes = str::to_bytes(~"ping"); + tcp_write_single(&sock, resp_bytes); + let read_result = sock.read(0u); + client_ch.send(str::from_bytes(read_result.get())); + }; + } fn impl_gl_tcp_ipv4_client_error_connection_refused() { let hl_loop = uv::global_loop::get(); let server_ip = ~"127.0.0.1"; @@ -1512,8 +1593,11 @@ mod test { ~"SERVER/WORKER: send on cont ch"); cont_ch.send(()); let sock = result::unwrap(move accept_result); + let peer_addr = sock.get_peer_addr(); log(debug, ~"SERVER: successfully accepted"+ - ~"connection!"); + fmt!(" connection from %s:%u", + ip::format_addr(&peer_addr), + ip::get_port(&peer_addr))); let received_req_bytes = read(&sock, 0u); match move received_req_bytes { result::Ok(move data) => { diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index 0ab4d89f363..8ea9513d155 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -65,10 +65,10 @@ fn encode_inner(s: &str, full_url: bool) -> ~str { str::push_char(&mut out, ch); } - _ => out += #fmt("%%%X", ch as uint) + _ => out += fmt!("%%%X", ch as uint) } } else { - out += #fmt("%%%X", ch as uint); + out += fmt!("%%%X", ch as uint); } } } @@ -94,6 +94,7 @@ pub fn encode(s: &str) -> ~str { * * This function is compliant with RFC 3986. */ + pub fn encode_component(s: &str) -> ~str { encode_inner(s, false) } @@ -163,7 +164,7 @@ fn encode_plus(s: &str) -> ~str { str::push_char(&mut out, ch); } ' ' => str::push_char(&mut out, '+'), - _ => out += #fmt("%%%X", ch as uint) + _ => out += fmt!("%%%X", ch as uint) } } @@ -189,7 +190,7 @@ pub fn encode_form_urlencoded(m: HashMap<~str, @DVec<@~str>>) -> ~str { first = false; } - out += #fmt("%s=%s", key, encode_plus(**value)); + out += fmt!("%s=%s", key, encode_plus(**value)); } } @@ -297,7 +298,7 @@ fn userinfo_from_str(uinfo: &str) -> UserInfo { return UserInfo(user, pass); } -fn userinfo_to_str(userinfo: UserInfo) -> ~str { +pure fn userinfo_to_str(userinfo: UserInfo) -> ~str { if option::is_some(&userinfo.pass) { return str::concat(~[copy userinfo.user, ~":", option::unwrap(copy userinfo.pass), @@ -325,11 +326,15 @@ fn query_from_str(rawquery: &str) -> Query { return query; } -pub fn query_to_str(query: Query) -> ~str { +pub pure fn query_to_str(query: Query) -> ~str { let mut strvec = ~[]; for query.each |kv| { let (k, v) = copy *kv; - strvec += ~[#fmt("%s=%s", encode_component(k), encode_component(v))]; + // This is really safe... + unsafe { + strvec += ~[fmt!("%s=%s", + encode_component(k), encode_component(v))]; + } }; return str::connect(strvec, ~"&"); } @@ -672,7 +677,7 @@ impl Url : FromStr { * result in just "http://somehost.com". * */ -pub fn to_str(url: Url) -> ~str { +pub pure fn to_str(url: Url) -> ~str { let user = if url.user.is_some() { userinfo_to_str(option::unwrap(copy url.user)) } else { @@ -688,7 +693,8 @@ pub fn to_str(url: Url) -> ~str { } else { str::concat(~[~"?", query_to_str(url.query)]) }; - let fragment = if url.fragment.is_some() { + // ugh, this really is safe + let fragment = if url.fragment.is_some() unsafe { str::concat(~[~"#", encode_component( option::unwrap(copy url.fragment))]) } else { @@ -704,7 +710,7 @@ pub fn to_str(url: Url) -> ~str { } impl Url: to_str::ToStr { - pub fn to_str() -> ~str { + pub pure fn to_str() -> ~str { to_str(self) } } @@ -844,7 +850,7 @@ mod tests { fn test_url_parse_host_slash() { let urlstr = ~"http://0.42.42.42/"; let url = from_str(urlstr).get(); - #debug("url: %?", url); + debug!("url: %?", url); assert url.host == ~"0.42.42.42"; assert url.path == ~"/"; } @@ -853,7 +859,7 @@ mod tests { fn test_url_with_underscores() { let urlstr = ~"http://dotcom.com/file_name.html"; let url = from_str(urlstr).get(); - #debug("url: %?", url); + debug!("url: %?", url); assert url.path == ~"/file_name.html"; } @@ -861,7 +867,7 @@ mod tests { fn test_url_with_dashes() { let urlstr = ~"http://dotcom.com/file-name.html"; let url = from_str(urlstr).get(); - #debug("url: %?", url); + debug!("url: %?", url); assert url.path == ~"/file-name.html"; } diff --git a/src/libstd/prettyprint.rs b/src/libstd/prettyprint.rs index bc528800666..6119c03cdca 100644 --- a/src/libstd/prettyprint.rs +++ b/src/libstd/prettyprint.rs @@ -2,131 +2,175 @@ use io::Writer; use io::WriterUtil; -use serialization::Serializer; +use serialization; -impl Writer: Serializer { - fn emit_nil() { - self.write_str(~"()") +pub struct Serializer { + wr: io::Writer, +} + +pub fn Serializer(wr: io::Writer) -> Serializer { + Serializer { wr: wr } +} + +pub impl Serializer: serialization::Serializer { + fn emit_nil(&self) { + self.wr.write_str(~"()") + } + + fn emit_uint(&self, v: uint) { + self.wr.write_str(fmt!("%?u", v)); + } + + fn emit_u64(&self, v: u64) { + self.wr.write_str(fmt!("%?_u64", v)); + } + + fn emit_u32(&self, v: u32) { + self.wr.write_str(fmt!("%?_u32", v)); + } + + fn emit_u16(&self, v: u16) { + self.wr.write_str(fmt!("%?_u16", v)); + } + + fn emit_u8(&self, v: u8) { + self.wr.write_str(fmt!("%?_u8", v)); } - fn emit_uint(v: uint) { - self.write_str(fmt!("%?u", v)); + fn emit_int(&self, v: int) { + self.wr.write_str(fmt!("%?", v)); } - fn emit_u64(v: u64) { - self.write_str(fmt!("%?_u64", v)); + fn emit_i64(&self, v: i64) { + self.wr.write_str(fmt!("%?_i64", v)); } - fn emit_u32(v: u32) { - self.write_str(fmt!("%?_u32", v)); + fn emit_i32(&self, v: i32) { + self.wr.write_str(fmt!("%?_i32", v)); } - fn emit_u16(v: u16) { - self.write_str(fmt!("%?_u16", v)); + fn emit_i16(&self, v: i16) { + self.wr.write_str(fmt!("%?_i16", v)); } - fn emit_u8(v: u8) { - self.write_str(fmt!("%?_u8", v)); + fn emit_i8(&self, v: i8) { + self.wr.write_str(fmt!("%?_i8", v)); } - fn emit_int(v: int) { - self.write_str(fmt!("%?", v)); + fn emit_bool(&self, v: bool) { + self.wr.write_str(fmt!("%b", v)); } - fn emit_i64(v: i64) { - self.write_str(fmt!("%?_i64", v)); + fn emit_float(&self, v: float) { + self.wr.write_str(fmt!("%?_f", v)); } - fn emit_i32(v: i32) { - self.write_str(fmt!("%?_i32", v)); + fn emit_f64(&self, v: f64) { + self.wr.write_str(fmt!("%?_f64", v)); } - fn emit_i16(v: i16) { - self.write_str(fmt!("%?_i16", v)); + fn emit_f32(&self, v: f32) { + self.wr.write_str(fmt!("%?_f32", v)); } - fn emit_i8(v: i8) { - self.write_str(fmt!("%?_i8", v)); + fn emit_char(&self, v: char) { + self.wr.write_str(fmt!("%?", v)); } - fn emit_bool(v: bool) { - self.write_str(fmt!("%b", v)); + fn emit_borrowed_str(&self, v: &str) { + self.wr.write_str(fmt!("&%?", v)); } - fn emit_float(v: float) { - self.write_str(fmt!("%?_f", v)); + fn emit_owned_str(&self, v: &str) { + self.wr.write_str(fmt!("~%?", v)); } - fn emit_f64(v: f64) { - self.write_str(fmt!("%?_f64", v)); + fn emit_managed_str(&self, v: &str) { + self.wr.write_str(fmt!("@%?", v)); } - fn emit_f32(v: f32) { - self.write_str(fmt!("%?_f32", v)); + fn emit_borrowed(&self, f: fn()) { + self.wr.write_str(~"&"); + f(); } - fn emit_str(v: &str) { - self.write_str(fmt!("%?", v)); + fn emit_owned(&self, f: fn()) { + self.wr.write_str(~"~"); + f(); + } + + fn emit_managed(&self, f: fn()) { + self.wr.write_str(~"@"); + f(); + } + + fn emit_enum(&self, _name: &str, f: fn()) { + f(); } - fn emit_enum(_name: &str, f: fn()) { + fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint, + f: fn()) { + self.wr.write_str(v_name); + if sz > 0u { self.wr.write_str(~"("); } f(); + if sz > 0u { self.wr.write_str(~")"); } } - fn emit_enum_variant(v_name: &str, _v_id: uint, sz: uint, f: fn()) { - self.write_str(v_name); - if sz > 0u { self.write_str(~"("); } + fn emit_enum_variant_arg(&self, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } f(); - if sz > 0u { self.write_str(~")"); } } - fn emit_enum_variant_arg(idx: uint, f: fn()) { - if idx > 0u { self.write_str(~", "); } + fn emit_borrowed_vec(&self, _len: uint, f: fn()) { + self.wr.write_str(~"&["); f(); + self.wr.write_str(~"]"); } - fn emit_vec(_len: uint, f: fn()) { - self.write_str(~"["); + fn emit_owned_vec(&self, _len: uint, f: fn()) { + self.wr.write_str(~"~["); f(); - self.write_str(~"]"); + self.wr.write_str(~"]"); } - fn emit_vec_elt(idx: uint, f: fn()) { - if idx > 0u { self.write_str(~", "); } + fn emit_managed_vec(&self, _len: uint, f: fn()) { + self.wr.write_str(~"@["); f(); + self.wr.write_str(~"]"); } - fn emit_box(f: fn()) { - self.write_str(~"@"); + fn emit_vec_elt(&self, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } f(); } - fn emit_uniq(f: fn()) { - self.write_str(~"~"); + fn emit_rec(&self, f: fn()) { + self.wr.write_str(~"{"); f(); + self.wr.write_str(~"}"); } - fn emit_rec(f: fn()) { - self.write_str(~"{"); + fn emit_struct(&self, name: &str, f: fn()) { + self.wr.write_str(fmt!("%s {", name)); f(); - self.write_str(~"}"); + self.wr.write_str(~"}"); } - fn emit_rec_field(f_name: &str, f_idx: uint, f: fn()) { - if f_idx > 0u { self.write_str(~", "); } - self.write_str(f_name); - self.write_str(~": "); + fn emit_field(&self, name: &str, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } + self.wr.write_str(name); + self.wr.write_str(~": "); f(); } - fn emit_tup(_sz: uint, f: fn()) { - self.write_str(~"("); + fn emit_tup(&self, _len: uint, f: fn()) { + self.wr.write_str(~"("); f(); - self.write_str(~")"); + self.wr.write_str(~")"); } - fn emit_tup_elt(idx: uint, f: fn()) { - if idx > 0u { self.write_str(~", "); } + fn emit_tup_elt(&self, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } f(); } } diff --git a/src/libstd/prettyprint2.rs b/src/libstd/prettyprint2.rs deleted file mode 100644 index 87af519eb12..00000000000 --- a/src/libstd/prettyprint2.rs +++ /dev/null @@ -1,176 +0,0 @@ -#[forbid(deprecated_mode)]; - -use io::Writer; -use io::WriterUtil; -use serialization2; - -pub struct Serializer { - wr: io::Writer, -} - -pub fn Serializer(wr: io::Writer) -> Serializer { - Serializer { wr: wr } -} - -pub impl Serializer: serialization2::Serializer { - fn emit_nil(&self) { - self.wr.write_str(~"()") - } - - fn emit_uint(&self, v: uint) { - self.wr.write_str(fmt!("%?u", v)); - } - - fn emit_u64(&self, v: u64) { - self.wr.write_str(fmt!("%?_u64", v)); - } - - fn emit_u32(&self, v: u32) { - self.wr.write_str(fmt!("%?_u32", v)); - } - - fn emit_u16(&self, v: u16) { - self.wr.write_str(fmt!("%?_u16", v)); - } - - fn emit_u8(&self, v: u8) { - self.wr.write_str(fmt!("%?_u8", v)); - } - - fn emit_int(&self, v: int) { - self.wr.write_str(fmt!("%?", v)); - } - - fn emit_i64(&self, v: i64) { - self.wr.write_str(fmt!("%?_i64", v)); - } - - fn emit_i32(&self, v: i32) { - self.wr.write_str(fmt!("%?_i32", v)); - } - - fn emit_i16(&self, v: i16) { - self.wr.write_str(fmt!("%?_i16", v)); - } - - fn emit_i8(&self, v: i8) { - self.wr.write_str(fmt!("%?_i8", v)); - } - - fn emit_bool(&self, v: bool) { - self.wr.write_str(fmt!("%b", v)); - } - - fn emit_float(&self, v: float) { - self.wr.write_str(fmt!("%?_f", v)); - } - - fn emit_f64(&self, v: f64) { - self.wr.write_str(fmt!("%?_f64", v)); - } - - fn emit_f32(&self, v: f32) { - self.wr.write_str(fmt!("%?_f32", v)); - } - - fn emit_char(&self, v: char) { - self.wr.write_str(fmt!("%?", v)); - } - - fn emit_borrowed_str(&self, v: &str) { - self.wr.write_str(fmt!("&%?", v)); - } - - fn emit_owned_str(&self, v: &str) { - self.wr.write_str(fmt!("~%?", v)); - } - - fn emit_managed_str(&self, v: &str) { - self.wr.write_str(fmt!("@%?", v)); - } - - fn emit_borrowed(&self, f: fn()) { - self.wr.write_str(~"&"); - f(); - } - - fn emit_owned(&self, f: fn()) { - self.wr.write_str(~"~"); - f(); - } - - fn emit_managed(&self, f: fn()) { - self.wr.write_str(~"@"); - f(); - } - - fn emit_enum(&self, _name: &str, f: fn()) { - f(); - } - - fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint, - f: fn()) { - self.wr.write_str(v_name); - if sz > 0u { self.wr.write_str(~"("); } - f(); - if sz > 0u { self.wr.write_str(~")"); } - } - - fn emit_enum_variant_arg(&self, idx: uint, f: fn()) { - if idx > 0u { self.wr.write_str(~", "); } - f(); - } - - fn emit_borrowed_vec(&self, _len: uint, f: fn()) { - self.wr.write_str(~"&["); - f(); - self.wr.write_str(~"]"); - } - - fn emit_owned_vec(&self, _len: uint, f: fn()) { - self.wr.write_str(~"~["); - f(); - self.wr.write_str(~"]"); - } - - fn emit_managed_vec(&self, _len: uint, f: fn()) { - self.wr.write_str(~"@["); - f(); - self.wr.write_str(~"]"); - } - - fn emit_vec_elt(&self, idx: uint, f: fn()) { - if idx > 0u { self.wr.write_str(~", "); } - f(); - } - - fn emit_rec(&self, f: fn()) { - self.wr.write_str(~"{"); - f(); - self.wr.write_str(~"}"); - } - - fn emit_struct(&self, name: &str, f: fn()) { - self.wr.write_str(fmt!("%s {", name)); - f(); - self.wr.write_str(~"}"); - } - - fn emit_field(&self, name: &str, idx: uint, f: fn()) { - if idx > 0u { self.wr.write_str(~", "); } - self.wr.write_str(name); - self.wr.write_str(~": "); - f(); - } - - fn emit_tup(&self, _len: uint, f: fn()) { - self.wr.write_str(~"("); - f(); - self.wr.write_str(~")"); - } - - fn emit_tup_elt(&self, idx: uint, f: fn()) { - if idx > 0u { self.wr.write_str(~", "); } - f(); - } -} diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs index 8ba00e65dec..9df2a326a84 100644 --- a/src/libstd/serialization.rs +++ b/src/libstd/serialization.rs @@ -1,81 +1,532 @@ //! Support code for serialization. -#[allow(deprecated_mode)]; - /* Core serialization interfaces. */ +#[forbid(deprecated_mode)]; +#[forbid(non_camel_case_types)]; + pub trait Serializer { // Primitive types: - fn emit_nil(); - fn emit_uint(v: uint); - fn emit_u64(v: u64); - fn emit_u32(v: u32); - fn emit_u16(v: u16); - fn emit_u8(v: u8); - fn emit_int(v: int); - fn emit_i64(v: i64); - fn emit_i32(v: i32); - fn emit_i16(v: i16); - fn emit_i8(v: i8); - fn emit_bool(v: bool); - fn emit_float(v: float); - fn emit_f64(v: f64); - fn emit_f32(v: f32); - fn emit_str(v: &str); + fn emit_nil(&self); + fn emit_uint(&self, v: uint); + fn emit_u64(&self, v: u64); + fn emit_u32(&self, v: u32); + fn emit_u16(&self, v: u16); + fn emit_u8(&self, v: u8); + fn emit_int(&self, v: int); + fn emit_i64(&self, v: i64); + fn emit_i32(&self, v: i32); + fn emit_i16(&self, v: i16); + fn emit_i8(&self, v: i8); + fn emit_bool(&self, v: bool); + fn emit_float(&self, v: float); + fn emit_f64(&self, v: f64); + fn emit_f32(&self, v: f32); + fn emit_char(&self, v: char); + fn emit_borrowed_str(&self, v: &str); + fn emit_owned_str(&self, v: &str); + fn emit_managed_str(&self, v: &str); // Compound types: - fn emit_enum(name: &str, f: fn()); - fn emit_enum_variant(v_name: &str, v_id: uint, sz: uint, f: fn()); - fn emit_enum_variant_arg(idx: uint, f: fn()); - fn emit_vec(len: uint, f: fn()); - fn emit_vec_elt(idx: uint, f: fn()); - fn emit_box(f: fn()); - fn emit_uniq(f: fn()); - fn emit_rec(f: fn()); - fn emit_rec_field(f_name: &str, f_idx: uint, f: fn()); - fn emit_tup(sz: uint, f: fn()); - fn emit_tup_elt(idx: uint, f: fn()); + fn emit_borrowed(&self, f: fn()); + fn emit_owned(&self, f: fn()); + fn emit_managed(&self, f: fn()); + + fn emit_enum(&self, name: &str, f: fn()); + fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn()); + fn emit_enum_variant_arg(&self, idx: uint, f: fn()); + + fn emit_borrowed_vec(&self, len: uint, f: fn()); + fn emit_owned_vec(&self, len: uint, f: fn()); + fn emit_managed_vec(&self, len: uint, f: fn()); + fn emit_vec_elt(&self, idx: uint, f: fn()); + + fn emit_rec(&self, f: fn()); + fn emit_struct(&self, name: &str, f: fn()); + fn emit_field(&self, f_name: &str, f_idx: uint, f: fn()); + + fn emit_tup(&self, len: uint, f: fn()); + fn emit_tup_elt(&self, idx: uint, f: fn()); } pub trait Deserializer { // Primitive types: - fn read_nil() -> (); + fn read_nil(&self) -> (); + fn read_uint(&self) -> uint; + fn read_u64(&self) -> u64; + fn read_u32(&self) -> u32; + fn read_u16(&self) -> u16; + fn read_u8(&self) -> u8; + fn read_int(&self) -> int; + fn read_i64(&self) -> i64; + fn read_i32(&self) -> i32; + fn read_i16(&self) -> i16; + fn read_i8(&self) -> i8; + fn read_bool(&self) -> bool; + fn read_f64(&self) -> f64; + fn read_f32(&self) -> f32; + fn read_float(&self) -> float; + fn read_char(&self) -> char; + fn read_owned_str(&self) -> ~str; + fn read_managed_str(&self) -> @str; - fn read_uint() -> uint; - fn read_u64() -> u64; - fn read_u32() -> u32; - fn read_u16() -> u16; - fn read_u8() -> u8; + // Compound types: + fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T; + fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T; + fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T; - fn read_int() -> int; - fn read_i64() -> i64; - fn read_i32() -> i32; - fn read_i16() -> i16; - fn read_i8() -> i8; + fn read_owned<T>(&self, f: fn() -> T) -> T; + fn read_managed<T>(&self, f: fn() -> T) -> T; + fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T; + fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T; + fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T; - fn read_bool() -> bool; + fn read_rec<T>(&self, f: fn() -> T) -> T; + fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T; + fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T; - fn read_str() -> ~str; + fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T; + fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T; +} - fn read_f64() -> f64; - fn read_f32() -> f32; - fn read_float() -> float; +#[cfg(stage0)] +pub mod traits { +pub trait Serializable { + fn serialize<S: Serializer>(&self, s: &S); +} - // Compound types: - fn read_enum<T>(name: &str, f: fn() -> T) -> T; - fn read_enum_variant<T>(f: fn(uint) -> T) -> T; - fn read_enum_variant_arg<T>(idx: uint, f: fn() -> T) -> T; - fn read_vec<T>(f: fn(uint) -> T) -> T; - fn read_vec_elt<T>(idx: uint, f: fn() -> T) -> T; - fn read_box<T>(f: fn() -> T) -> T; - fn read_uniq<T>(f: fn() -> T) -> T; - fn read_rec<T>(f: fn() -> T) -> T; - fn read_rec_field<T>(f_name: &str, f_idx: uint, f: fn() -> T) -> T; - fn read_tup<T>(sz: uint, f: fn() -> T) -> T; - fn read_tup_elt<T>(idx: uint, f: fn() -> T) -> T; +pub trait Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> self; +} + +pub impl uint: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_uint(*self) } +} + +pub impl uint: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> uint { + d.read_uint() + } +} + +pub impl u8: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_u8(*self) } +} + +pub impl u8: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> u8 { + d.read_u8() + } +} + +pub impl u16: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_u16(*self) } +} + +pub impl u16: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> u16 { + d.read_u16() + } +} + +pub impl u32: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_u32(*self) } +} + +pub impl u32: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> u32 { + d.read_u32() + } +} + +pub impl u64: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_u64(*self) } +} + +pub impl u64: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> u64 { + d.read_u64() + } +} + +pub impl int: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_int(*self) } +} + +pub impl int: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> int { + d.read_int() + } +} + +pub impl i8: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_i8(*self) } +} + +pub impl i8: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> i8 { + d.read_i8() + } +} + +pub impl i16: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_i16(*self) } +} + +pub impl i16: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> i16 { + d.read_i16() + } +} + +pub impl i32: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_i32(*self) } +} + +pub impl i32: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> i32 { + d.read_i32() + } +} + +pub impl i64: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_i64(*self) } +} + +pub impl i64: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> i64 { + d.read_i64() + } +} + +pub impl &str: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_borrowed_str(*self) } +} + +pub impl ~str: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_owned_str(*self) } +} + +pub impl ~str: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> ~str { + d.read_owned_str() + } +} + +pub impl @str: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_managed_str(*self) } +} + +pub impl @str: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> @str { + d.read_managed_str() + } +} + +pub impl float: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_float(*self) } +} + +pub impl float: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> float { + d.read_float() + } +} + +pub impl f32: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_f32(*self) } +} + +pub impl f32: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> f32 { + d.read_f32() } +} + +pub impl f64: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_f64(*self) } +} + +pub impl f64: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> f64 { + d.read_f64() + } +} + +pub impl bool: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_bool(*self) } +} + +pub impl bool: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> bool { + d.read_bool() + } +} + +pub impl (): Serializable { + fn serialize<S: Serializer>(&self, s: &S) { s.emit_nil() } +} + +pub impl (): Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> () { + d.read_nil() + } +} + +pub impl<T: Serializable> &T: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { + s.emit_borrowed(|| (**self).serialize(s)) + } +} + +pub impl<T: Serializable> ~T: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { + s.emit_owned(|| (**self).serialize(s)) + } +} + +pub impl<T: Deserializable> ~T: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> ~T { + d.read_owned(|| ~deserialize(d)) + } +} + +pub impl<T: Serializable> @T: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { + s.emit_managed(|| (**self).serialize(s)) + } +} + +pub impl<T: Deserializable> @T: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> @T { + d.read_managed(|| @deserialize(d)) + } +} + +pub impl<T: Serializable> &[T]: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { + do s.emit_borrowed_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl<T: Serializable> ~[T]: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { + do s.emit_owned_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl<T: Deserializable> ~[T]: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> ~[T] { + do d.read_owned_vec |len| { + do vec::from_fn(len) |i| { + d.read_vec_elt(i, || deserialize(d)) + } + } + } +} + +pub impl<T: Serializable> @[T]: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { + do s.emit_managed_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl<T: Deserializable> @[T]: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> @[T] { + do d.read_managed_vec |len| { + do at_vec::from_fn(len) |i| { + d.read_vec_elt(i, || deserialize(d)) + } + } + } +} + +pub impl<T: Serializable> Option<T>: Serializable { + fn serialize<S: Serializer>(&self, s: &S) { + do s.emit_enum(~"option") { + match *self { + None => do s.emit_enum_variant(~"none", 0u, 0u) { + }, + + Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) { + s.emit_enum_variant_arg(0u, || v.serialize(s)) + } + } + } + } +} + +pub impl<T: Deserializable> Option<T>: Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> Option<T> { + do d.read_enum(~"option") { + do d.read_enum_variant |i| { + match i { + 0 => None, + 1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))), + _ => fail(fmt!("Bad variant for option: %u", i)) + } + } + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable +> (T0, T1): Serializable { + fn serialize<S: Serializer>(&self, s: &S) { + match *self { + (ref t0, ref t1) => { + do s.emit_tup(2) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable +> (T0, T1): Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1) { + do d.read_tup(2) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)) + ) + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable, + T2: Serializable +> (T0, T1, T2): Serializable { + fn serialize<S: Serializer>(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2) => { + do s.emit_tup(3) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable, + T2: Deserializable +> (T0, T1, T2): Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2) { + do d.read_tup(3) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)) + ) + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable, + T2: Serializable, + T3: Serializable +> (T0, T1, T2, T3): Serializable { + fn serialize<S: Serializer>(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2, ref t3) => { + do s.emit_tup(4) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + s.emit_tup_elt(3, || t3.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable, + T2: Deserializable, + T3: Deserializable +> (T0, T1, T2, T3): Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2, T3) { + do d.read_tup(4) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)), + d.read_tup_elt(3, || deserialize(d)) + ) + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable, + T2: Serializable, + T3: Serializable, + T4: Serializable +> (T0, T1, T2, T3, T4): Serializable { + fn serialize<S: Serializer>(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2, ref t3, ref t4) => { + do s.emit_tup(5) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + s.emit_tup_elt(3, || t3.serialize(s)); + s.emit_tup_elt(4, || t4.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable, + T2: Deserializable, + T3: Deserializable, + T4: Deserializable +> (T0, T1, T2, T3, T4): Deserializable { + static fn deserialize<D: Deserializer>(&self, d: &D) + -> (T0, T1, T2, T3, T4) { + do d.read_tup(5) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)), + d.read_tup_elt(3, || deserialize(d)), + d.read_tup_elt(4, || deserialize(d)) + ) + } + } } // ___________________________________________________________________________ @@ -83,189 +534,517 @@ pub trait Deserializer { // // In some cases, these should eventually be coded as traits. -pub fn emit_from_vec<S: Serializer, T>(&&s: S, &&v: ~[T], f: fn(&&x: T)) { - do s.emit_vec(vec::len(v)) { - for vec::eachi(v) |i,e| { - do s.emit_vec_elt(i) { - f(*e) +pub trait SerializerHelpers { + fn emit_from_vec<T>(&self, v: &[T], f: fn(&T)); +} + +pub impl<S: Serializer> S: SerializerHelpers { + fn emit_from_vec<T>(&self, v: &[T], f: fn(&T)) { + do self.emit_owned_vec(v.len()) { + for v.eachi |i, e| { + do self.emit_vec_elt(i) { + f(e) + } } } } } -pub fn read_to_vec<D: Deserializer, T: Copy>(&&d: D, f: fn() -> T) -> ~[T] { - do d.read_vec |len| { - do vec::from_fn(len) |i| { - d.read_vec_elt(i, || f()) +pub trait DeserializerHelpers { + fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T]; +} + +pub impl<D: Deserializer> D: DeserializerHelpers { + fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] { + do self.read_owned_vec |len| { + do vec::from_fn(len) |i| { + self.read_vec_elt(i, || f()) + } } } } +} -pub trait SerializerHelpers { - fn emit_from_vec<T>(&&v: ~[T], f: fn(&&x: T)); +#[cfg(stage1)] +#[cfg(stage2)] +pub mod traits { +pub trait Serializable<S: Serializer> { + fn serialize(&self, s: &S); +} + +pub trait Deserializable<D: Deserializer> { + static fn deserialize(&self, d: &D) -> self; +} + +pub impl<S: Serializer> uint: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_uint(*self) } } -impl<S: Serializer> S: SerializerHelpers { - fn emit_from_vec<T>(&&v: ~[T], f: fn(&&x: T)) { - emit_from_vec(self, v, f) +pub impl<D: Deserializer> uint: Deserializable<D> { + static fn deserialize(&self, d: &D) -> uint { + d.read_uint() } } -pub trait DeserializerHelpers { - fn read_to_vec<T: Copy>(f: fn() -> T) -> ~[T]; +pub impl<S: Serializer> u8: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_u8(*self) } +} + +pub impl<D: Deserializer> u8: Deserializable<D> { + static fn deserialize(&self, d: &D) -> u8 { + d.read_u8() + } +} + +pub impl<S: Serializer> u16: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_u16(*self) } +} + +pub impl<D: Deserializer> u16: Deserializable<D> { + static fn deserialize(&self, d: &D) -> u16 { + d.read_u16() + } +} + +pub impl<S: Serializer> u32: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_u32(*self) } +} + +pub impl<D: Deserializer> u32: Deserializable<D> { + static fn deserialize(&self, d: &D) -> u32 { + d.read_u32() + } +} + +pub impl<S: Serializer> u64: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_u64(*self) } +} + +pub impl<D: Deserializer> u64: Deserializable<D> { + static fn deserialize(&self, d: &D) -> u64 { + d.read_u64() + } +} + +pub impl<S: Serializer> int: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_int(*self) } +} + +pub impl<D: Deserializer> int: Deserializable<D> { + static fn deserialize(&self, d: &D) -> int { + d.read_int() + } +} + +pub impl<S: Serializer> i8: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_i8(*self) } +} + +pub impl<D: Deserializer> i8: Deserializable<D> { + static fn deserialize(&self, d: &D) -> i8 { + d.read_i8() + } +} + +pub impl<S: Serializer> i16: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_i16(*self) } +} + +pub impl<D: Deserializer> i16: Deserializable<D> { + static fn deserialize(&self, d: &D) -> i16 { + d.read_i16() + } +} + +pub impl<S: Serializer> i32: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_i32(*self) } +} + +pub impl<D: Deserializer> i32: Deserializable<D> { + static fn deserialize(&self, d: &D) -> i32 { + d.read_i32() + } +} + +pub impl<S: Serializer> i64: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_i64(*self) } } -impl<D: Deserializer> D: DeserializerHelpers { - fn read_to_vec<T: Copy>(f: fn() -> T) -> ~[T] { - read_to_vec(self, f) +pub impl<D: Deserializer> i64: Deserializable<D> { + static fn deserialize(&self, d: &D) -> i64 { + d.read_i64() } } -pub fn serialize_uint<S: Serializer>(&&s: S, v: uint) { - s.emit_uint(v); +pub impl<S: Serializer> &str: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_borrowed_str(*self) } +} + +pub impl<S: Serializer> ~str: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_owned_str(*self) } } -pub fn deserialize_uint<D: Deserializer>(&&d: D) -> uint { - d.read_uint() +pub impl<D: Deserializer> ~str: Deserializable<D> { + static fn deserialize(&self, d: &D) -> ~str { + d.read_owned_str() + } } -pub fn serialize_u8<S: Serializer>(&&s: S, v: u8) { - s.emit_u8(v); +pub impl<S: Serializer> @str: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_managed_str(*self) } } -pub fn deserialize_u8<D: Deserializer>(&&d: D) -> u8 { - d.read_u8() +pub impl<D: Deserializer> @str: Deserializable<D> { + static fn deserialize(&self, d: &D) -> @str { + d.read_managed_str() + } } -pub fn serialize_u16<S: Serializer>(&&s: S, v: u16) { - s.emit_u16(v); +pub impl<S: Serializer> float: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_float(*self) } } -pub fn deserialize_u16<D: Deserializer>(&&d: D) -> u16 { - d.read_u16() +pub impl<D: Deserializer> float: Deserializable<D> { + static fn deserialize(&self, d: &D) -> float { + d.read_float() + } } -pub fn serialize_u32<S: Serializer>(&&s: S, v: u32) { - s.emit_u32(v); +pub impl<S: Serializer> f32: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_f32(*self) } } -pub fn deserialize_u32<D: Deserializer>(&&d: D) -> u32 { - d.read_u32() +pub impl<D: Deserializer> f32: Deserializable<D> { + static fn deserialize(&self, d: &D) -> f32 { + d.read_f32() } } -pub fn serialize_u64<S: Serializer>(&&s: S, v: u64) { - s.emit_u64(v); +pub impl<S: Serializer> f64: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_f64(*self) } } -pub fn deserialize_u64<D: Deserializer>(&&d: D) -> u64 { - d.read_u64() +pub impl<D: Deserializer> f64: Deserializable<D> { + static fn deserialize(&self, d: &D) -> f64 { + d.read_f64() + } } -pub fn serialize_int<S: Serializer>(&&s: S, v: int) { - s.emit_int(v); +pub impl<S: Serializer> bool: Serializable<S> { + fn serialize(&self, s: &S) { s.emit_bool(*self) } } -pub fn deserialize_int<D: Deserializer>(&&d: D) -> int { - d.read_int() +pub impl<D: Deserializer> bool: Deserializable<D> { + static fn deserialize(&self, d: &D) -> bool { + d.read_bool() + } } -pub fn serialize_i8<S: Serializer>(&&s: S, v: i8) { - s.emit_i8(v); +pub impl<S: Serializer> (): Serializable<S> { + fn serialize(&self, s: &S) { s.emit_nil() } } -pub fn deserialize_i8<D: Deserializer>(&&d: D) -> i8 { - d.read_i8() +pub impl<D: Deserializer> (): Deserializable<D> { + static fn deserialize(&self, d: &D) -> () { + d.read_nil() + } } -pub fn serialize_i16<S: Serializer>(&&s: S, v: i16) { - s.emit_i16(v); +pub impl<S: Serializer, T: Serializable<S>> &T: Serializable<S> { + fn serialize(&self, s: &S) { + s.emit_borrowed(|| (**self).serialize(s)) + } } -pub fn deserialize_i16<D: Deserializer>(&&d: D) -> i16 { - d.read_i16() +pub impl<S: Serializer, T: Serializable<S>> ~T: Serializable<S> { + fn serialize(&self, s: &S) { + s.emit_owned(|| (**self).serialize(s)) + } } -pub fn serialize_i32<S: Serializer>(&&s: S, v: i32) { - s.emit_i32(v); +pub impl<D: Deserializer, T: Deserializable<D>> ~T: Deserializable<D> { + static fn deserialize(&self, d: &D) -> ~T { + d.read_owned(|| ~deserialize(d)) + } } -pub fn deserialize_i32<D: Deserializer>(&&d: D) -> i32 { - d.read_i32() +pub impl<S: Serializer, T: Serializable<S>> @T: Serializable<S> { + fn serialize(&self, s: &S) { + s.emit_managed(|| (**self).serialize(s)) + } } -pub fn serialize_i64<S: Serializer>(&&s: S, v: i64) { - s.emit_i64(v); +pub impl<D: Deserializer, T: Deserializable<D>> @T: Deserializable<D> { + static fn deserialize(&self, d: &D) -> @T { + d.read_managed(|| @deserialize(d)) + } } -pub fn deserialize_i64<D: Deserializer>(&&d: D) -> i64 { - d.read_i64() +pub impl<S: Serializer, T: Serializable<S>> &[T]: Serializable<S> { + fn serialize(&self, s: &S) { + do s.emit_borrowed_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl<S: Serializer, T: Serializable<S>> ~[T]: Serializable<S> { + fn serialize(&self, s: &S) { + do s.emit_owned_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl<D: Deserializer, T: Deserializable<D>> ~[T]: Deserializable<D> { + static fn deserialize(&self, d: &D) -> ~[T] { + do d.read_owned_vec |len| { + do vec::from_fn(len) |i| { + d.read_vec_elt(i, || deserialize(d)) + } + } + } +} + +pub impl<S: Serializer, T: Serializable<S>> @[T]: Serializable<S> { + fn serialize(&self, s: &S) { + do s.emit_managed_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl<D: Deserializer, T: Deserializable<D>> @[T]: Deserializable<D> { + static fn deserialize(&self, d: &D) -> @[T] { + do d.read_managed_vec |len| { + do at_vec::from_fn(len) |i| { + d.read_vec_elt(i, || deserialize(d)) + } + } + } } -pub fn serialize_str<S: Serializer>(&&s: S, v: &str) { - s.emit_str(v); +pub impl<S: Serializer, T: Serializable<S>> Option<T>: Serializable<S> { + fn serialize(&self, s: &S) { + do s.emit_enum(~"option") { + match *self { + None => do s.emit_enum_variant(~"none", 0u, 0u) { + }, + + Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) { + s.emit_enum_variant_arg(0u, || v.serialize(s)) + } + } + } + } } -pub fn deserialize_str<D: Deserializer>(&&d: D) -> ~str { - d.read_str() +pub impl<D: Deserializer, T: Deserializable<D>> Option<T>: Deserializable<D> { + static fn deserialize(&self, d: &D) -> Option<T> { + do d.read_enum(~"option") { + do d.read_enum_variant |i| { + match i { + 0 => None, + 1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))), + _ => fail(#fmt("Bad variant for option: %u", i)) + } + } + } + } } -pub fn serialize_float<S: Serializer>(&&s: S, v: float) { - s.emit_float(v); +pub impl< + S: Serializer, + T0: Serializable<S>, + T1: Serializable<S> +> (T0, T1): Serializable<S> { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1) => { + do s.emit_tup(2) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + } + } + } + } } -pub fn deserialize_float<D: Deserializer>(&&d: D) -> float { - d.read_float() +pub impl< + D: Deserializer, + T0: Deserializable<D>, + T1: Deserializable<D> +> (T0, T1): Deserializable<D> { + static fn deserialize(&self, d: &D) -> (T0, T1) { + do d.read_tup(2) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)) + ) + } + } } -pub fn serialize_f32<S: Serializer>(&&s: S, v: f32) { - s.emit_f32(v); +pub impl< + S: Serializer, + T0: Serializable<S>, + T1: Serializable<S>, + T2: Serializable<S> +> (T0, T1, T2): Serializable<S> { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2) => { + do s.emit_tup(3) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + } + } + } + } } -pub fn deserialize_f32<D: Deserializer>(&&d: D) -> f32 { - d.read_f32() +pub impl< + D: Deserializer, + T0: Deserializable<D>, + T1: Deserializable<D>, + T2: Deserializable<D> +> (T0, T1, T2): Deserializable<D> { + static fn deserialize(&self, d: &D) -> (T0, T1, T2) { + do d.read_tup(3) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)) + ) + } + } } -pub fn serialize_f64<S: Serializer>(&&s: S, v: f64) { - s.emit_f64(v); +pub impl< + S: Serializer, + T0: Serializable<S>, + T1: Serializable<S>, + T2: Serializable<S>, + T3: Serializable<S> +> (T0, T1, T2, T3): Serializable<S> { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2, ref t3) => { + do s.emit_tup(4) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + s.emit_tup_elt(3, || t3.serialize(s)); + } + } + } + } } -pub fn deserialize_f64<D: Deserializer>(&&d: D) -> f64 { - d.read_f64() +pub impl< + D: Deserializer, + T0: Deserializable<D>, + T1: Deserializable<D>, + T2: Deserializable<D>, + T3: Deserializable<D> +> (T0, T1, T2, T3): Deserializable<D> { + static fn deserialize(&self, d: &D) -> (T0, T1, T2, T3) { + do d.read_tup(4) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)), + d.read_tup_elt(3, || deserialize(d)) + ) + } + } } -pub fn serialize_bool<S: Serializer>(&&s: S, v: bool) { - s.emit_bool(v); +pub impl< + S: Serializer, + T0: Serializable<S>, + T1: Serializable<S>, + T2: Serializable<S>, + T3: Serializable<S>, + T4: Serializable<S> +> (T0, T1, T2, T3, T4): Serializable<S> { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2, ref t3, ref t4) => { + do s.emit_tup(5) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + s.emit_tup_elt(3, || t3.serialize(s)); + s.emit_tup_elt(4, || t4.serialize(s)); + } + } + } + } } -pub fn deserialize_bool<D: Deserializer>(&&d: D) -> bool { - d.read_bool() +pub impl< + D: Deserializer, + T0: Deserializable<D>, + T1: Deserializable<D>, + T2: Deserializable<D>, + T3: Deserializable<D>, + T4: Deserializable<D> +> (T0, T1, T2, T3, T4): Deserializable<D> { + static fn deserialize(&self, d: &D) + -> (T0, T1, T2, T3, T4) { + do d.read_tup(5) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)), + d.read_tup_elt(3, || deserialize(d)), + d.read_tup_elt(4, || deserialize(d)) + ) + } + } } -pub fn serialize_Option<S: Serializer,T>(&&s: S, &&v: Option<T>, - st: fn(&&x: T)) { - do s.emit_enum(~"option") { - match v { - None => do s.emit_enum_variant(~"none", 0u, 0u) { - }, +// ___________________________________________________________________________ +// Helper routines +// +// In some cases, these should eventually be coded as traits. - Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) { - do s.emit_enum_variant_arg(0u) { - st(*v) +pub trait SerializerHelpers { + fn emit_from_vec<T>(&self, v: ~[T], f: fn(v: &T)); +} + +pub impl<S: Serializer> S: SerializerHelpers { + fn emit_from_vec<T>(&self, v: ~[T], f: fn(v: &T)) { + do self.emit_owned_vec(v.len()) { + for v.eachi |i, e| { + do self.emit_vec_elt(i) { + f(e) + } } - } } } } -pub fn deserialize_Option<D: Deserializer,T: Copy>(&&d: D, st: fn() -> T) - -> Option<T> { - do d.read_enum(~"option") { - do d.read_enum_variant |i| { - match i { - 0 => None, - 1 => Some(d.read_enum_variant_arg(0u, || st() )), - _ => fail(#fmt("Bad variant for option: %u", i)) +pub trait DeserializerHelpers { + fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T]; +} + +pub impl<D: Deserializer> D: DeserializerHelpers { + fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] { + do self.read_owned_vec |len| { + do vec::from_fn(len) |i| { + self.read_vec_elt(i, || f()) } } } } +} + +pub use traits::*; diff --git a/src/libstd/serialization2.rs b/src/libstd/serialization2.rs deleted file mode 100644 index 5173ef163a2..00000000000 --- a/src/libstd/serialization2.rs +++ /dev/null @@ -1,563 +0,0 @@ -//! Support code for serialization. - -/* -Core serialization interfaces. -*/ - -#[forbid(deprecated_mode)]; -#[forbid(non_camel_case_types)]; - -pub trait Serializer { - // Primitive types: - fn emit_nil(&self); - fn emit_uint(&self, v: uint); - fn emit_u64(&self, v: u64); - fn emit_u32(&self, v: u32); - fn emit_u16(&self, v: u16); - fn emit_u8(&self, v: u8); - fn emit_int(&self, v: int); - fn emit_i64(&self, v: i64); - fn emit_i32(&self, v: i32); - fn emit_i16(&self, v: i16); - fn emit_i8(&self, v: i8); - fn emit_bool(&self, v: bool); - fn emit_float(&self, v: float); - fn emit_f64(&self, v: f64); - fn emit_f32(&self, v: f32); - fn emit_char(&self, v: char); - fn emit_borrowed_str(&self, v: &str); - fn emit_owned_str(&self, v: &str); - fn emit_managed_str(&self, v: &str); - - // Compound types: - fn emit_borrowed(&self, f: fn()); - fn emit_owned(&self, f: fn()); - fn emit_managed(&self, f: fn()); - - fn emit_enum(&self, name: &str, f: fn()); - fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn()); - fn emit_enum_variant_arg(&self, idx: uint, f: fn()); - - fn emit_borrowed_vec(&self, len: uint, f: fn()); - fn emit_owned_vec(&self, len: uint, f: fn()); - fn emit_managed_vec(&self, len: uint, f: fn()); - fn emit_vec_elt(&self, idx: uint, f: fn()); - - fn emit_rec(&self, f: fn()); - fn emit_struct(&self, name: &str, f: fn()); - fn emit_field(&self, f_name: &str, f_idx: uint, f: fn()); - - fn emit_tup(&self, len: uint, f: fn()); - fn emit_tup_elt(&self, idx: uint, f: fn()); -} - -pub trait Deserializer { - // Primitive types: - fn read_nil(&self) -> (); - fn read_uint(&self) -> uint; - fn read_u64(&self) -> u64; - fn read_u32(&self) -> u32; - fn read_u16(&self) -> u16; - fn read_u8(&self) -> u8; - fn read_int(&self) -> int; - fn read_i64(&self) -> i64; - fn read_i32(&self) -> i32; - fn read_i16(&self) -> i16; - fn read_i8(&self) -> i8; - fn read_bool(&self) -> bool; - fn read_f64(&self) -> f64; - fn read_f32(&self) -> f32; - fn read_float(&self) -> float; - fn read_char(&self) -> char; - fn read_owned_str(&self) -> ~str; - fn read_managed_str(&self) -> @str; - - // Compound types: - fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T; - fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T; - fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T; - - fn read_owned<T>(&self, f: fn() -> T) -> T; - fn read_managed<T>(&self, f: fn() -> T) -> T; - - fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T; - fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T; - fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T; - - fn read_rec<T>(&self, f: fn() -> T) -> T; - fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T; - fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T; - - fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T; - fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T; -} - -pub trait Serializable { - fn serialize<S: Serializer>(&self, s: &S); -} - -pub trait Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> self; -} - -pub impl uint: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_uint(*self) } -} - -pub impl uint: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> uint { - d.read_uint() - } -} - -pub impl u8: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_u8(*self) } -} - -pub impl u8: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> u8 { - d.read_u8() - } -} - -pub impl u16: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_u16(*self) } -} - -pub impl u16: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> u16 { - d.read_u16() - } -} - -pub impl u32: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_u32(*self) } -} - -pub impl u32: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> u32 { - d.read_u32() - } -} - -pub impl u64: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_u64(*self) } -} - -pub impl u64: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> u64 { - d.read_u64() - } -} - -pub impl int: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_int(*self) } -} - -pub impl int: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> int { - d.read_int() - } -} - -pub impl i8: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_i8(*self) } -} - -pub impl i8: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> i8 { - d.read_i8() - } -} - -pub impl i16: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_i16(*self) } -} - -pub impl i16: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> i16 { - d.read_i16() - } -} - -pub impl i32: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_i32(*self) } -} - -pub impl i32: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> i32 { - d.read_i32() - } -} - -pub impl i64: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_i64(*self) } -} - -pub impl i64: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> i64 { - d.read_i64() - } -} - -pub impl &str: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_borrowed_str(*self) } -} - -pub impl ~str: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_owned_str(*self) } -} - -pub impl ~str: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> ~str { - d.read_owned_str() - } -} - -pub impl @str: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_managed_str(*self) } -} - -pub impl @str: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> @str { - d.read_managed_str() - } -} - -pub impl float: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_float(*self) } -} - -pub impl float: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> float { - d.read_float() - } -} - -pub impl f32: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_f32(*self) } -} - -pub impl f32: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> f32 { - d.read_f32() } -} - -pub impl f64: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_f64(*self) } -} - -pub impl f64: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> f64 { - d.read_f64() - } -} - -pub impl bool: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_bool(*self) } -} - -pub impl bool: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> bool { - d.read_bool() - } -} - -pub impl (): Serializable { - fn serialize<S: Serializer>(&self, s: &S) { s.emit_nil() } -} - -pub impl (): Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> () { - d.read_nil() - } -} - -pub impl<T: Serializable> &T: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { - s.emit_borrowed(|| (**self).serialize(s)) - } -} - -pub impl<T: Serializable> ~T: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { - s.emit_owned(|| (**self).serialize(s)) - } -} - -pub impl<T: Deserializable> ~T: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> ~T { - d.read_owned(|| ~deserialize(d)) - } -} - -pub impl<T: Serializable> @T: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { - s.emit_managed(|| (**self).serialize(s)) - } -} - -pub impl<T: Deserializable> @T: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> @T { - d.read_managed(|| @deserialize(d)) - } -} - -pub impl<T: Serializable> &[T]: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { - do s.emit_borrowed_vec(self.len()) { - for self.eachi |i, e| { - s.emit_vec_elt(i, || e.serialize(s)) - } - } - } -} - -pub impl<T: Serializable> ~[T]: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { - do s.emit_owned_vec(self.len()) { - for self.eachi |i, e| { - s.emit_vec_elt(i, || e.serialize(s)) - } - } - } -} - -pub impl<T: Deserializable> ~[T]: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> ~[T] { - do d.read_owned_vec |len| { - do vec::from_fn(len) |i| { - d.read_vec_elt(i, || deserialize(d)) - } - } - } -} - -pub impl<T: Serializable> @[T]: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { - do s.emit_managed_vec(self.len()) { - for self.eachi |i, e| { - s.emit_vec_elt(i, || e.serialize(s)) - } - } - } -} - -pub impl<T: Deserializable> @[T]: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> @[T] { - do d.read_managed_vec |len| { - do at_vec::from_fn(len) |i| { - d.read_vec_elt(i, || deserialize(d)) - } - } - } -} - -pub impl<T: Serializable> Option<T>: Serializable { - fn serialize<S: Serializer>(&self, s: &S) { - do s.emit_enum(~"option") { - match *self { - None => do s.emit_enum_variant(~"none", 0u, 0u) { - }, - - Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) { - s.emit_enum_variant_arg(0u, || v.serialize(s)) - } - } - } - } -} - -pub impl<T: Deserializable> Option<T>: Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> Option<T> { - do d.read_enum(~"option") { - do d.read_enum_variant |i| { - match i { - 0 => None, - 1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))), - _ => fail(#fmt("Bad variant for option: %u", i)) - } - } - } - } -} - -pub impl< - T0: Serializable, - T1: Serializable -> (T0, T1): Serializable { - fn serialize<S: Serializer>(&self, s: &S) { - match *self { - (ref t0, ref t1) => { - do s.emit_tup(2) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - } - } - } - } -} - -pub impl< - T0: Deserializable, - T1: Deserializable -> (T0, T1): Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1) { - do d.read_tup(2) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)) - ) - } - } -} - -pub impl< - T0: Serializable, - T1: Serializable, - T2: Serializable -> (T0, T1, T2): Serializable { - fn serialize<S: Serializer>(&self, s: &S) { - match *self { - (ref t0, ref t1, ref t2) => { - do s.emit_tup(3) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - s.emit_tup_elt(2, || t2.serialize(s)); - } - } - } - } -} - -pub impl< - T0: Deserializable, - T1: Deserializable, - T2: Deserializable -> (T0, T1, T2): Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2) { - do d.read_tup(3) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)), - d.read_tup_elt(2, || deserialize(d)) - ) - } - } -} - -pub impl< - T0: Serializable, - T1: Serializable, - T2: Serializable, - T3: Serializable -> (T0, T1, T2, T3): Serializable { - fn serialize<S: Serializer>(&self, s: &S) { - match *self { - (ref t0, ref t1, ref t2, ref t3) => { - do s.emit_tup(4) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - s.emit_tup_elt(2, || t2.serialize(s)); - s.emit_tup_elt(3, || t3.serialize(s)); - } - } - } - } -} - -pub impl< - T0: Deserializable, - T1: Deserializable, - T2: Deserializable, - T3: Deserializable -> (T0, T1, T2, T3): Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2, T3) { - do d.read_tup(4) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)), - d.read_tup_elt(2, || deserialize(d)), - d.read_tup_elt(3, || deserialize(d)) - ) - } - } -} - -pub impl< - T0: Serializable, - T1: Serializable, - T2: Serializable, - T3: Serializable, - T4: Serializable -> (T0, T1, T2, T3, T4): Serializable { - fn serialize<S: Serializer>(&self, s: &S) { - match *self { - (ref t0, ref t1, ref t2, ref t3, ref t4) => { - do s.emit_tup(5) { - s.emit_tup_elt(0, || t0.serialize(s)); - s.emit_tup_elt(1, || t1.serialize(s)); - s.emit_tup_elt(2, || t2.serialize(s)); - s.emit_tup_elt(3, || t3.serialize(s)); - s.emit_tup_elt(4, || t4.serialize(s)); - } - } - } - } -} - -pub impl< - T0: Deserializable, - T1: Deserializable, - T2: Deserializable, - T3: Deserializable, - T4: Deserializable -> (T0, T1, T2, T3, T4): Deserializable { - static fn deserialize<D: Deserializer>(&self, d: &D) - -> (T0, T1, T2, T3, T4) { - do d.read_tup(5) { - ( - d.read_tup_elt(0, || deserialize(d)), - d.read_tup_elt(1, || deserialize(d)), - d.read_tup_elt(2, || deserialize(d)), - d.read_tup_elt(3, || deserialize(d)), - d.read_tup_elt(4, || deserialize(d)) - ) - } - } -} - -// ___________________________________________________________________________ -// Helper routines -// -// In some cases, these should eventually be coded as traits. - -pub trait SerializerHelpers { - fn emit_from_vec<T>(&self, v: &[T], f: fn(&T)); -} - -pub impl<S: Serializer> S: SerializerHelpers { - fn emit_from_vec<T>(&self, v: &[T], f: fn(&T)) { - do self.emit_owned_vec(v.len()) { - for v.eachi |i, e| { - do self.emit_vec_elt(i) { - f(e) - } - } - } - } -} - -pub trait DeserializerHelpers { - fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T]; -} - -pub impl<D: Deserializer> D: DeserializerHelpers { - fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] { - do self.read_owned_vec |len| { - do vec::from_fn(len) |i| { - self.read_vec_elt(i, || f()) - } - } - } -} diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index 98f98fe7fce..946a3e1155d 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -899,7 +899,7 @@ mod test_qsort { do sort::quick_sort(names) |x, y| { int::le(*x, *y) }; - let immut_names = vec::from_mut(names); + let immut_names = vec::from_mut(move names); let pairs = vec::zip(expected, immut_names); for vec::each(pairs) |p| { diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 7fc3004bbcf..bbffde40948 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -8,7 +8,7 @@ not required in or otherwise suitable for the core library. */ #[link(name = "std", - vers = "0.4", + vers = "0.5", uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297", url = "https://github.com/mozilla/rust/tree/master/src/libstd")]; @@ -25,7 +25,7 @@ not required in or otherwise suitable for the core library. #[allow(deprecated_mode)]; #[forbid(deprecated_pattern)]; -extern mod core(vers = "0.4"); +extern mod core(vers = "0.5"); use core::*; // General io and system-services modules @@ -69,7 +69,6 @@ pub mod treemap; // And ... other stuff pub mod ebml; -pub mod ebml2; pub mod dbg; pub mod getopts; pub mod json; @@ -79,7 +78,6 @@ pub mod tempfile; pub mod term; pub mod time; pub mod prettyprint; -pub mod prettyprint2; pub mod arena; pub mod par; pub mod cmp; @@ -93,7 +91,6 @@ mod unicode; pub mod test; pub mod serialization; -pub mod serialization2; // Local Variables: // mode: rust; diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index 908f3936f4e..73fc78a091a 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -25,7 +25,7 @@ struct Waitqueue { head: pipes::Port<SignalEnd>, fn new_waitqueue() -> Waitqueue { let (block_tail, block_head) = pipes::stream(); - Waitqueue { head: block_head, tail: block_tail } + Waitqueue { head: move block_head, tail: move block_tail } } // Signals one live task from the queue. @@ -71,7 +71,7 @@ enum Sem<Q: Send> = Exclusive<SemInner<Q>>; #[doc(hidden)] fn new_sem<Q: Send>(count: int, q: Q) -> Sem<Q> { Sem(exclusive(SemInner { - mut count: count, waiters: new_waitqueue(), blocked: q })) + mut count: count, waiters: new_waitqueue(), blocked: move q })) } #[doc(hidden)] fn new_sem_and_signal(count: int, num_condvars: uint) @@ -146,7 +146,7 @@ impl &Sem<~[mut Waitqueue]> { } } -// FIXME(#3136) should go inside of access() +// FIXME(#3588) should go inside of access() #[doc(hidden)] struct SemRelease { sem: &Sem<()>, @@ -577,7 +577,7 @@ impl &RWlock { } } -// FIXME(#3136) should go inside of read() +// FIXME(#3588) should go inside of read() #[doc(hidden)] struct RWlockReleaseRead { lock: &RWlock, @@ -606,7 +606,7 @@ fn RWlockReleaseRead(lock: &r/RWlock) -> RWlockReleaseRead/&r { } } -// FIXME(#3136) should go inside of downgrade() +// FIXME(#3588) should go inside of downgrade() #[doc(hidden)] struct RWlockReleaseDowngrade { lock: &RWlock, @@ -686,7 +686,7 @@ mod tests { fn test_sem_as_mutex() { let s = ~semaphore(1); let s2 = ~s.clone(); - do task::spawn { + do task::spawn |move s2| { do s2.access { for 5.times { task::yield(); } } @@ -701,7 +701,7 @@ mod tests { let (c,p) = pipes::stream(); let s = ~semaphore(0); let s2 = ~s.clone(); - do task::spawn { + do task::spawn |move s2, move c| { s2.acquire(); c.send(()); } @@ -713,7 +713,7 @@ mod tests { let (c,p) = pipes::stream(); let s = ~semaphore(0); let s2 = ~s.clone(); - do task::spawn { + do task::spawn |move s2, move p| { for 5.times { task::yield(); } s2.release(); let _ = p.recv(); @@ -729,7 +729,7 @@ mod tests { let s2 = ~s.clone(); let (c1,p1) = pipes::stream(); let (c2,p2) = pipes::stream(); - do task::spawn { + do task::spawn |move s2, move c1, move p2| { do s2.access { let _ = p2.recv(); c1.send(()); @@ -748,10 +748,10 @@ mod tests { let s = ~semaphore(1); let s2 = ~s.clone(); let (c,p) = pipes::stream(); - let child_data = ~mut Some((s2,c)); + let child_data = ~mut Some((move s2, move c)); do s.access { let (s2,c) = option::swap_unwrap(child_data); - do task::spawn { + do task::spawn |move c, move s2| { c.send(()); do s2.access { } c.send(()); @@ -774,7 +774,7 @@ mod tests { let m2 = ~m.clone(); let mut sharedstate = ~0; let ptr = ptr::addr_of(&(*sharedstate)); - do task::spawn { + do task::spawn |move m2, move c| { let sharedstate: &mut int = unsafe { cast::reinterpret_cast(&ptr) }; access_shared(sharedstate, m2, 10); @@ -803,7 +803,7 @@ mod tests { // Child wakes up parent do m.lock_cond |cond| { let m2 = ~m.clone(); - do task::spawn { + do task::spawn |move m2| { do m2.lock_cond |cond| { let woken = cond.signal(); assert woken; @@ -814,7 +814,7 @@ mod tests { // Parent wakes up child let (chan,port) = pipes::stream(); let m3 = ~m.clone(); - do task::spawn { + do task::spawn |move chan, move m3| { do m3.lock_cond |cond| { chan.send(()); cond.wait(); @@ -836,8 +836,8 @@ mod tests { for num_waiters.times { let mi = ~m.clone(); let (chan, port) = pipes::stream(); - ports.push(port); - do task::spawn { + ports.push(move port); + do task::spawn |move chan, move mi| { do mi.lock_cond |cond| { chan.send(()); cond.wait(); @@ -867,7 +867,7 @@ mod tests { fn test_mutex_cond_no_waiter() { let m = ~Mutex(); let m2 = ~m.clone(); - do task::try { + do task::try |move m| { do m.lock_cond |_x| { } }; do m2.lock_cond |cond| { @@ -880,7 +880,7 @@ mod tests { let m = ~Mutex(); let m2 = ~m.clone(); - let result: result::Result<(),()> = do task::try { + let result: result::Result<(),()> = do task::try |move m2| { do m2.lock { fail; } @@ -896,9 +896,9 @@ mod tests { let m = ~Mutex(); let m2 = ~m.clone(); - let result: result::Result<(),()> = do task::try { + let result: result::Result<(),()> = do task::try |move m2| { let (c,p) = pipes::stream(); - do task::spawn { // linked + do task::spawn |move p| { // linked let _ = p.recv(); // wait for sibling to get in the mutex task::yield(); fail; @@ -921,19 +921,19 @@ mod tests { let m2 = ~m.clone(); let (c,p) = pipes::stream(); - let result: result::Result<(),()> = do task::try { + let result: result::Result<(),()> = do task::try |move c, move m2| { let mut sibling_convos = ~[]; for 2.times { let (c,p) = pipes::stream(); - let c = ~mut Some(c); - sibling_convos.push(p); + let c = ~mut Some(move c); + sibling_convos.push(move p); let mi = ~m2.clone(); // spawn sibling task - do task::spawn { // linked + do task::spawn |move mi, move c| { // linked do mi.lock_cond |cond| { let c = option::swap_unwrap(c); c.send(()); // tell sibling to go ahead - let _z = SendOnFailure(c); + let _z = SendOnFailure(move c); cond.wait(); // block forever } } @@ -942,7 +942,7 @@ mod tests { let _ = p.recv(); // wait for sibling to get in the mutex } do m2.lock { } - c.send(sibling_convos); // let parent wait on all children + c.send(move sibling_convos); // let parent wait on all children fail; }; assert result.is_err(); @@ -959,7 +959,7 @@ mod tests { fn SendOnFailure(c: pipes::Chan<()>) -> SendOnFailure { SendOnFailure { - c: c + c: move c } } } @@ -969,7 +969,7 @@ mod tests { let m = ~Mutex(); do m.lock_cond |cond| { let m2 = ~m.clone(); - do task::spawn { + do task::spawn |move m2| { do m2.lock_cond |cond| { cond.signal_on(0); } @@ -983,7 +983,7 @@ mod tests { let m = ~mutex_with_condvars(2); let m2 = ~m.clone(); let (c,p) = pipes::stream(); - do task::spawn { + do task::spawn |move m2, move c| { do m2.lock_cond |cond| { c.send(()); cond.wait_on(1); @@ -1032,7 +1032,7 @@ mod tests { }, DowngradeRead => do x.write_downgrade |mode| { - let mode = x.downgrade(mode); + let mode = x.downgrade(move mode); (&mode).read(blk); }, } @@ -1046,7 +1046,7 @@ mod tests { let x2 = ~x.clone(); let mut sharedstate = ~0; let ptr = ptr::addr_of(&(*sharedstate)); - do task::spawn { + do task::spawn |move c, move x2| { let sharedstate: &mut int = unsafe { cast::reinterpret_cast(&ptr) }; access_shared(sharedstate, x2, mode1, 10); @@ -1089,7 +1089,7 @@ mod tests { let x2 = ~x.clone(); let (c1,p1) = pipes::stream(); let (c2,p2) = pipes::stream(); - do task::spawn { + do task::spawn |move c1, move x2, move p2| { if !make_mode2_go_first { let _ = p2.recv(); // parent sends to us once it locks, or ... } @@ -1126,10 +1126,10 @@ mod tests { // Tests that downgrade can unlock the lock in both modes let x = ~RWlock(); do lock_rwlock_in_mode(x, Downgrade) { } - test_rwlock_handshake(x, Read, Read, false); + test_rwlock_handshake(move x, Read, Read, false); let y = ~RWlock(); do lock_rwlock_in_mode(y, DowngradeRead) { } - test_rwlock_exclusion(y, Write, Write); + test_rwlock_exclusion(move y, Write, Write); } #[test] fn test_rwlock_read_recursive() { @@ -1144,7 +1144,7 @@ mod tests { // Child wakes up parent do x.write_cond |cond| { let x2 = ~x.clone(); - do task::spawn { + do task::spawn |move x2| { do x2.write_cond |cond| { let woken = cond.signal(); assert woken; @@ -1155,7 +1155,7 @@ mod tests { // Parent wakes up child let (chan,port) = pipes::stream(); let x3 = ~x.clone(); - do task::spawn { + do task::spawn |move x3, move chan| { do x3.write_cond |cond| { chan.send(()); cond.wait(); @@ -1190,8 +1190,8 @@ mod tests { for num_waiters.times { let xi = ~x.clone(); let (chan, port) = pipes::stream(); - ports.push(port); - do task::spawn { + ports.push(move port); + do task::spawn |move chan, move xi| { do lock_cond(xi, dg1) |cond| { chan.send(()); cond.wait(); @@ -1226,7 +1226,7 @@ mod tests { let x = ~RWlock(); let x2 = ~x.clone(); - let result: result::Result<(),()> = do task::try { + let result: result::Result<(),()> = do task::try |move x2| { do lock_rwlock_in_mode(x2, mode1) { fail; } @@ -1264,7 +1264,7 @@ mod tests { let x = ~RWlock(); let y = ~RWlock(); do x.write_downgrade |xwrite| { - let mut xopt = Some(xwrite); + let mut xopt = Some(move xwrite); do y.write_downgrade |_ywrite| { y.downgrade(option::swap_unwrap(&mut xopt)); error!("oops, y.downgrade(x) should have failed!"); diff --git a/src/libstd/test.rs b/src/libstd/test.rs index 9790622332a..a10997d7c35 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -130,7 +130,7 @@ pub fn run_tests_console(opts: &TestOpts, st.failed += 1u; write_failed(st.out, st.use_color); st.out.write_line(~""); - st.failures.push(test); + st.failures.push(move test); } TrIgnored => { st.ignored += 1u; @@ -249,7 +249,7 @@ fn should_sort_failures_before_printing_them() { mut passed: 0u, mut failed: 0u, mut ignored: 0u, - mut failures: ~[test_b, test_a]}; + mut failures: ~[move test_b, move test_a]}; print_failures(st); }; @@ -534,9 +534,9 @@ mod tests { for vec::each(names) |name| { let test = {name: *name, testfn: copy testfn, ignore: false, should_fail: false}; - tests.push(test); + tests.push(move test); } - tests + move tests }; let filtered = filter_tests(&opts, tests); @@ -549,7 +549,7 @@ mod tests { ~"test::parse_ignored_flag", ~"test::sort_tests"]; - let pairs = vec::zip(expected, filtered); + let pairs = vec::zip(expected, move filtered); for vec::each(pairs) |p| { match *p { diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 65872a013ab..75909273392 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -595,8 +595,7 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ~str> { fn strftime(format: &str, tm: Tm) -> ~str { fn parse_type(ch: char, tm: &Tm) -> ~str { //FIXME (#2350): Implement missing types. - let die = || #fmt("strftime: can't understand this format %c ", - ch); + let die = || fmt!("strftime: can't understand this format %c ", ch); match ch { 'A' => match tm.tm_wday as int { 0 => ~"Sunday", diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs index c9c28c4e1f0..199fba45914 100644 --- a/src/libstd/timer.rs +++ b/src/libstd/timer.rs @@ -23,7 +23,7 @@ use comm = core::comm; * * ch - a channel of type T to send a `val` on * * val - a value of type T to send over the provided `ch` */ -pub fn delayed_send<T: Copy Send>(iotask: IoTask, +pub fn delayed_send<T: Send>(iotask: IoTask, msecs: uint, ch: comm::Chan<T>, val: T) { unsafe { let timer_done_po = core::comm::Port::<()>(); @@ -55,7 +55,7 @@ pub fn delayed_send<T: Copy Send>(iotask: IoTask, // delayed_send_cb has been processed by libuv core::comm::recv(timer_done_po); // notify the caller immediately - core::comm::send(ch, copy(val)); + core::comm::send(ch, move(val)); // uv_close for this timer has been processed core::comm::recv(timer_done_po); }; diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 8ab0dc7f2e7..e4b6c9b5b9a 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -11,28 +11,28 @@ use core::cmp::{Eq, Ord}; use core::option::{Some, None}; use Option = core::Option; -pub type TreeMap<K, V> = @mut TreeEdge<K, V>; +pub type TreeMap<K: Copy Eq Ord, V: Copy> = @mut TreeEdge<K, V>; -type TreeEdge<K, V> = Option<@TreeNode<K, V>>; +type TreeEdge<K: Copy Eq Ord, V: Copy> = Option<@TreeNode<K, V>>; -enum TreeNode<K, V> = { +struct TreeNode<K: Copy Eq Ord, V: Copy> { key: K, mut value: V, mut left: TreeEdge<K, V>, mut right: TreeEdge<K, V> -}; +} /// Create a treemap -pub fn TreeMap<K, V>() -> TreeMap<K, V> { @mut None } +pub fn TreeMap<K: Copy Eq Ord, V: Copy>() -> TreeMap<K, V> { @mut None } /// Insert a value into the map pub fn insert<K: Copy Eq Ord, V: Copy>(m: &mut TreeEdge<K, V>, k: K, v: V) { match copy *m { None => { - *m = Some(@TreeNode({key: k, - mut value: v, - mut left: None, - mut right: None})); + *m = Some(@TreeNode {key: k, + mut value: v, + mut left: None, + mut right: None}); return; } Some(node) => { @@ -67,7 +67,8 @@ pub fn find<K: Copy Eq Ord, V: Copy>(m: &const TreeEdge<K, V>, k: K) } /// Visit all pairs in the map in order. -pub fn traverse<K, V: Copy>(m: &const TreeEdge<K, V>, f: fn((&K), (&V))) { +pub fn traverse<K: Copy Eq Ord, V: Copy>(m: &const TreeEdge<K, V>, + f: fn((&K), (&V))) { match copy *m { None => (), Some(node) => { @@ -79,6 +80,19 @@ pub fn traverse<K, V: Copy>(m: &const TreeEdge<K, V>, f: fn((&K), (&V))) { } } +/// Compare two treemaps and return true iff +/// they contain same keys and values +pub fn equals<K: Copy Eq Ord, V: Copy Eq>(t1: &const TreeEdge<K, V>, + t2: &const TreeEdge<K, V>) + -> bool { + let mut v1 = ~[]; + let mut v2 = ~[]; + traverse(t1, |k,v| { v1.push((copy *k, copy *v)) }); + traverse(t2, |k,v| { v2.push((copy *k, copy *v)) }); + return v1 == v2; +} + + #[cfg(test)] mod tests { #[legacy_exports]; @@ -128,6 +142,28 @@ mod tests { } #[test] + fn equality() { + let m1 = TreeMap(); + insert(m1, 3, ()); + insert(m1, 0, ()); + insert(m1, 4, ()); + insert(m1, 2, ()); + insert(m1, 1, ()); + let m2 = TreeMap(); + insert(m2, 2, ()); + insert(m2, 1, ()); + insert(m2, 3, ()); + insert(m2, 0, ()); + insert(m2, 4, ()); + + assert equals(m1, m2); + + let m3 = TreeMap(); + assert !equals(m1,m3); + + } + + #[test] fn u8_map() { let m = TreeMap(); diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index f8c3882d15e..8bf4e9ed3af 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -590,6 +590,8 @@ extern mod rustrt { -> libc::c_int; fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: libc::size_t) -> libc::c_int; + fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint; + fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint; // FIXME ref #2064 fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, @@ -606,6 +608,10 @@ extern mod rustrt { // FIXME ref #2064 fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in6) -> libc::c_int; + fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, + ++name: *sockaddr_in) -> libc::c_int; + fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, + ++name: *sockaddr_in6) ->libc::c_int; fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int, cb: *u8) -> libc::c_int; fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void) @@ -736,6 +742,16 @@ pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, addr_ptr); } +pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, + name: *sockaddr_in) -> libc::c_int { + return rustrt::rust_uv_tcp_getpeername(tcp_handle_ptr, name); +} + +pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, + name: *sockaddr_in6) ->libc::c_int { + return rustrt::rust_uv_tcp_getpeername6(tcp_handle_ptr, name); +} + pub unsafe fn listen<T>(stream: *T, backlog: libc::c_int, cb: *u8) -> libc::c_int { return rustrt::rust_uv_listen(stream as *libc::c_void, backlog, cb); @@ -857,6 +873,12 @@ pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str { } } } +pub unsafe fn ip4_port(src: &sockaddr_in) -> uint { + rustrt::rust_uv_ip4_port(to_unsafe_ptr(src)) as uint +} +pub unsafe fn ip6_port(src: &sockaddr_in6) -> uint { + rustrt::rust_uv_ip6_port(to_unsafe_ptr(src)) as uint +} pub unsafe fn timer_init(loop_ptr: *libc::c_void, timer_ptr: *uv_timer_t) -> libc::c_int { @@ -1048,7 +1070,7 @@ pub mod test { as *request_wrapper; let buf_base = get_base_from_buf(buf); let buf_len = get_len_from_buf(buf); - let bytes = vec::raw::from_buf(buf_base, buf_len as uint); + let bytes = vec::from_buf(buf_base, buf_len as uint); let read_chan = *((*client_data).read_chan); let msg_from_server = str::from_bytes(bytes); core::comm::send(read_chan, msg_from_server); @@ -1223,7 +1245,7 @@ pub mod test { buf_base as uint, buf_len as uint, nread)); - let bytes = vec::raw::from_buf(buf_base, buf_len); + let bytes = vec::from_buf(buf_base, buf_len); let request_str = str::from_bytes(bytes); let client_data = get_data_for_uv_handle( @@ -1462,7 +1484,7 @@ pub mod test { fn impl_uv_tcp_server_and_request() unsafe { let bind_ip = ~"0.0.0.0"; let request_ip = ~"127.0.0.1"; - let port = 8887; + let port = 8886; let kill_server_msg = ~"does a dog have buddha nature?"; let server_resp_msg = ~"mu!"; let client_port = core::comm::Port::<~str>(); |
