Make opaque::Encoder append-only and make it infallible
This commit is contained in:
parent
971f7d34d4
commit
14d3c6e8f4
@ -52,7 +52,8 @@ impl Fingerprint {
|
||||
pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult {
|
||||
let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) };
|
||||
|
||||
encoder.emit_raw_bytes(&bytes)
|
||||
encoder.emit_raw_bytes(&bytes);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result<Fingerprint, String> {
|
||||
@ -92,7 +93,7 @@ impl serialize::UseSpecializedEncodable for Fingerprint { }
|
||||
|
||||
impl serialize::UseSpecializedDecodable for Fingerprint { }
|
||||
|
||||
impl<'a> serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder<'a> {
|
||||
impl serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder {
|
||||
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
|
||||
f.encode_opaque(self)
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ pub trait TyEncoder: Encoder {
|
||||
fn position(&self) -> usize;
|
||||
}
|
||||
|
||||
impl<'buf> TyEncoder for opaque::Encoder<'buf> {
|
||||
impl TyEncoder for opaque::Encoder {
|
||||
#[inline]
|
||||
fn position(&self) -> usize {
|
||||
self.position()
|
||||
|
@ -979,7 +979,7 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'enc, 'a, 't
|
||||
}
|
||||
|
||||
impl<'enc, 'a, 'tcx> SpecializedEncoder<Fingerprint>
|
||||
for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder<'enc>>
|
||||
for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder>
|
||||
{
|
||||
fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
|
||||
f.encode_opaque(&mut self.encoder)
|
||||
@ -1057,7 +1057,7 @@ impl IntEncodedWithFixedSize {
|
||||
impl UseSpecializedEncodable for IntEncodedWithFixedSize {}
|
||||
impl UseSpecializedDecodable for IntEncodedWithFixedSize {}
|
||||
|
||||
impl<'enc> SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder<'enc> {
|
||||
impl SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder {
|
||||
fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> {
|
||||
let start_pos = self.position();
|
||||
for i in 0 .. IntEncodedWithFixedSize::ENCODED_SIZE {
|
||||
|
@ -230,8 +230,7 @@ impl WasmEncoder {
|
||||
}
|
||||
|
||||
fn u32(&mut self, val: u32) {
|
||||
let at = self.data.len();
|
||||
leb128::write_u32_leb128(&mut self.data, at, val);
|
||||
leb128::write_u32_leb128(&mut self.data, val);
|
||||
}
|
||||
|
||||
fn byte(&mut self, val: u8) {
|
||||
|
@ -25,6 +25,7 @@ use std::fs;
|
||||
use std::env;
|
||||
|
||||
use rustc::session::config::nightly_options;
|
||||
use rustc_serialize::opaque::Encoder;
|
||||
|
||||
/// The first few bytes of files generated by incremental compilation
|
||||
const FILE_MAGIC: &'static [u8] = b"RSIC";
|
||||
@ -37,17 +38,15 @@ const HEADER_FORMAT_VERSION: u16 = 0;
|
||||
/// the git commit hash.
|
||||
const RUSTC_VERSION: Option<&'static str> = option_env!("CFG_VERSION");
|
||||
|
||||
pub fn write_file_header<W: io::Write>(stream: &mut W) -> io::Result<()> {
|
||||
stream.write_all(FILE_MAGIC)?;
|
||||
stream.write_all(&[(HEADER_FORMAT_VERSION >> 0) as u8,
|
||||
(HEADER_FORMAT_VERSION >> 8) as u8])?;
|
||||
pub fn write_file_header(stream: &mut Encoder) {
|
||||
stream.emit_raw_bytes(FILE_MAGIC);
|
||||
stream.emit_raw_bytes(&[(HEADER_FORMAT_VERSION >> 0) as u8,
|
||||
(HEADER_FORMAT_VERSION >> 8) as u8]);
|
||||
|
||||
let rustc_version = rustc_version();
|
||||
assert_eq!(rustc_version.len(), (rustc_version.len() as u8) as usize);
|
||||
stream.write_all(&[rustc_version.len() as u8])?;
|
||||
stream.write_all(rustc_version.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
stream.emit_raw_bytes(&[rustc_version.len() as u8]);
|
||||
stream.emit_raw_bytes(rustc_version.as_bytes());
|
||||
}
|
||||
|
||||
/// Reads the contents of a file with a file header as defined in this module.
|
||||
|
@ -16,7 +16,6 @@ use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::join;
|
||||
use rustc_serialize::Encodable as RustcEncodable;
|
||||
use rustc_serialize::opaque::Encoder;
|
||||
use std::io::{self, Cursor};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
@ -98,7 +97,7 @@ pub fn save_work_product_index(sess: &Session,
|
||||
}
|
||||
|
||||
fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
|
||||
where F: FnOnce(&mut Encoder) -> io::Result<()>
|
||||
where F: FnOnce(&mut Encoder)
|
||||
{
|
||||
debug!("save: storing data in {}", path_buf.display());
|
||||
|
||||
@ -121,20 +120,12 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
|
||||
}
|
||||
|
||||
// generate the data in a memory buffer
|
||||
let mut wr = Cursor::new(Vec::new());
|
||||
file_format::write_file_header(&mut wr).unwrap();
|
||||
match encode(&mut Encoder::new(&mut wr)) {
|
||||
Ok(()) => {}
|
||||
Err(err) => {
|
||||
sess.err(&format!("could not encode dep-graph to `{}`: {}",
|
||||
path_buf.display(),
|
||||
err));
|
||||
return;
|
||||
}
|
||||
}
|
||||
let mut encoder = Encoder::new(Vec::new());
|
||||
file_format::write_file_header(&mut encoder);
|
||||
encode(&mut encoder);
|
||||
|
||||
// write the data out
|
||||
let data = wr.into_inner();
|
||||
let data = encoder.into_inner();
|
||||
match fs::write(&path_buf, data) {
|
||||
Ok(_) => {
|
||||
debug!("save: data written to disk successfully");
|
||||
@ -149,10 +140,9 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
|
||||
}
|
||||
|
||||
fn encode_dep_graph(tcx: TyCtxt,
|
||||
encoder: &mut Encoder)
|
||||
-> io::Result<()> {
|
||||
encoder: &mut Encoder) {
|
||||
// First encode the commandline arguments hash
|
||||
tcx.sess.opts.dep_tracking_hash().encode(encoder)?;
|
||||
tcx.sess.opts.dep_tracking_hash().encode(encoder).unwrap();
|
||||
|
||||
// Encode the graph data.
|
||||
let serialized_graph = time(tcx.sess, "getting serialized graph", || {
|
||||
@ -234,14 +224,12 @@ fn encode_dep_graph(tcx: TyCtxt,
|
||||
}
|
||||
|
||||
time(tcx.sess, "encoding serialized graph", || {
|
||||
serialized_graph.encode(encoder)
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
serialized_graph.encode(encoder).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
fn encode_work_product_index(work_products: &FxHashMap<WorkProductId, WorkProduct>,
|
||||
encoder: &mut Encoder) -> io::Result<()> {
|
||||
encoder: &mut Encoder) {
|
||||
let serialized_products: Vec<_> = work_products
|
||||
.iter()
|
||||
.map(|(id, work_product)| {
|
||||
@ -252,13 +240,12 @@ fn encode_work_product_index(work_products: &FxHashMap<WorkProductId, WorkProduc
|
||||
})
|
||||
.collect();
|
||||
|
||||
serialized_products.encode(encoder)
|
||||
serialized_products.encode(encoder).unwrap();
|
||||
}
|
||||
|
||||
fn encode_query_cache(tcx: TyCtxt,
|
||||
encoder: &mut Encoder)
|
||||
-> io::Result<()> {
|
||||
encoder: &mut Encoder) {
|
||||
time(tcx.sess, "serialize query result cache", || {
|
||||
tcx.serialize_query_result_cache(encoder)
|
||||
tcx.serialize_query_result_cache(encoder).unwrap();
|
||||
})
|
||||
}
|
||||
|
@ -35,8 +35,6 @@ use rustc_data_structures::stable_hasher::StableHasher;
|
||||
use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
|
||||
|
||||
use std::hash::Hash;
|
||||
use std::io::prelude::*;
|
||||
use std::io::Cursor;
|
||||
use std::path::Path;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use std::u32;
|
||||
@ -52,7 +50,7 @@ use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
|
||||
use rustc::hir::intravisit;
|
||||
|
||||
pub struct EncodeContext<'a, 'tcx: 'a> {
|
||||
opaque: opaque::Encoder<'a>,
|
||||
opaque: opaque::Encoder,
|
||||
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
link_meta: &'a LinkMeta,
|
||||
|
||||
@ -76,7 +74,7 @@ macro_rules! encoder_methods {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
|
||||
type Error = <opaque::Encoder<'a> as Encoder>::Error;
|
||||
type Error = <opaque::Encoder as Encoder>::Error;
|
||||
|
||||
fn emit_nil(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(())
|
||||
@ -480,7 +478,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
|
||||
// Index the items
|
||||
i = self.position();
|
||||
let index = items.write_index(&mut self.opaque.cursor);
|
||||
let index = items.write_index(&mut self.opaque);
|
||||
let index_bytes = self.position() - i;
|
||||
|
||||
let attrs = tcx.hir.krate_attrs();
|
||||
@ -537,7 +535,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
|
||||
if self.tcx.sess.meta_stats() {
|
||||
let mut zero_bytes = 0;
|
||||
for e in self.opaque.cursor.get_ref() {
|
||||
for e in self.opaque.data.iter() {
|
||||
if *e == 0 {
|
||||
zero_bytes += 1;
|
||||
}
|
||||
@ -1797,15 +1795,15 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
link_meta: &LinkMeta)
|
||||
-> EncodedMetadata
|
||||
{
|
||||
let mut cursor = Cursor::new(vec![]);
|
||||
cursor.write_all(METADATA_HEADER).unwrap();
|
||||
let mut encoder = opaque::Encoder::new(vec![]);
|
||||
encoder.emit_raw_bytes(METADATA_HEADER);
|
||||
|
||||
// Will be filled with the root position after encoding everything.
|
||||
cursor.write_all(&[0, 0, 0, 0]).unwrap();
|
||||
encoder.emit_raw_bytes(&[0, 0, 0, 0]);
|
||||
|
||||
let root = {
|
||||
let (root, mut result) = {
|
||||
let mut ecx = EncodeContext {
|
||||
opaque: opaque::Encoder::new(&mut cursor),
|
||||
opaque: encoder,
|
||||
tcx,
|
||||
link_meta,
|
||||
lazy_state: LazyState::NoNode,
|
||||
@ -1821,9 +1819,9 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
// Encode all the entries and extra information in the crate,
|
||||
// culminating in the `CrateRoot` which points to all of it.
|
||||
ecx.encode_crate_root()
|
||||
let root = ecx.encode_crate_root();
|
||||
(root, ecx.opaque.into_inner())
|
||||
};
|
||||
let mut result = cursor.into_inner();
|
||||
|
||||
// Encode the root position.
|
||||
let header = METADATA_HEADER.len();
|
||||
|
@ -11,7 +11,7 @@
|
||||
use schema::*;
|
||||
|
||||
use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace};
|
||||
use std::io::{Cursor, Write};
|
||||
use rustc_serialize::opaque::Encoder;
|
||||
use std::slice;
|
||||
use std::u32;
|
||||
|
||||
@ -54,15 +54,15 @@ impl Index {
|
||||
self.positions[space_index][array_index] = position.to_le();
|
||||
}
|
||||
|
||||
pub fn write_index(&self, buf: &mut Cursor<Vec<u8>>) -> LazySeq<Index> {
|
||||
pub fn write_index(&self, buf: &mut Encoder) -> LazySeq<Index> {
|
||||
let pos = buf.position();
|
||||
|
||||
// First we write the length of the lower range ...
|
||||
buf.write_all(words_to_bytes(&[(self.positions[0].len() as u32).to_le()])).unwrap();
|
||||
buf.emit_raw_bytes(words_to_bytes(&[(self.positions[0].len() as u32).to_le()]));
|
||||
// ... then the values in the lower range ...
|
||||
buf.write_all(words_to_bytes(&self.positions[0][..])).unwrap();
|
||||
buf.emit_raw_bytes(words_to_bytes(&self.positions[0][..]));
|
||||
// ... then the values in the higher range.
|
||||
buf.write_all(words_to_bytes(&self.positions[1][..])).unwrap();
|
||||
buf.emit_raw_bytes(words_to_bytes(&self.positions[1][..]));
|
||||
LazySeq::with_position_and_length(pos as usize,
|
||||
self.positions[0].len() + self.positions[1].len() + 1)
|
||||
}
|
||||
|
@ -9,12 +9,8 @@
|
||||
// except according to those terms.
|
||||
|
||||
#[inline]
|
||||
pub fn write_to_vec(vec: &mut Vec<u8>, position: usize, byte: u8) {
|
||||
if position == vec.len() {
|
||||
vec.push(byte);
|
||||
} else {
|
||||
vec[position] = byte;
|
||||
}
|
||||
pub fn write_to_vec(vec: &mut Vec<u8>, byte: u8) {
|
||||
vec.push(byte);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
@ -33,8 +29,7 @@ macro_rules! leb128_size {
|
||||
macro_rules! impl_write_unsigned_leb128 {
|
||||
($fn_name:ident, $int_ty:ident) => (
|
||||
#[inline]
|
||||
pub fn $fn_name(out: &mut Vec<u8>, start_position: usize, mut value: $int_ty) -> usize {
|
||||
let mut position = start_position;
|
||||
pub fn $fn_name(out: &mut Vec<u8>, mut value: $int_ty) {
|
||||
for _ in 0 .. leb128_size!($int_ty) {
|
||||
let mut byte = (value & 0x7F) as u8;
|
||||
value >>= 7;
|
||||
@ -42,15 +37,12 @@ macro_rules! impl_write_unsigned_leb128 {
|
||||
byte |= 0x80;
|
||||
}
|
||||
|
||||
write_to_vec(out, position, byte);
|
||||
position += 1;
|
||||
write_to_vec(out, byte);
|
||||
|
||||
if value == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
position - start_position
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -105,11 +97,9 @@ impl_read_unsigned_leb128!(read_usize_leb128, usize);
|
||||
/// The callback `write` is called once for each position
|
||||
/// that is to be written to with the byte to be encoded
|
||||
/// at that position.
|
||||
pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
|
||||
where W: FnMut(usize, u8)
|
||||
pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W)
|
||||
where W: FnMut(u8)
|
||||
{
|
||||
let mut position = 0;
|
||||
|
||||
loop {
|
||||
let mut byte = (value as u8) & 0x7f;
|
||||
value >>= 7;
|
||||
@ -120,18 +110,16 @@ pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
|
||||
byte |= 0x80; // Mark this byte to show that more bytes will follow.
|
||||
}
|
||||
|
||||
write(position, byte);
|
||||
position += 1;
|
||||
write(byte);
|
||||
|
||||
if !more {
|
||||
break;
|
||||
}
|
||||
}
|
||||
position
|
||||
}
|
||||
|
||||
pub fn write_signed_leb128(out: &mut Vec<u8>, start_position: usize, value: i128) -> usize {
|
||||
write_signed_leb128_to(value, |i, v| write_to_vec(out, start_position+i, v))
|
||||
pub fn write_signed_leb128(out: &mut Vec<u8>, value: i128) {
|
||||
write_signed_leb128_to(value, |v| write_to_vec(out, v))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -167,9 +155,7 @@ macro_rules! impl_test_unsigned_leb128 {
|
||||
let mut stream = Vec::new();
|
||||
|
||||
for x in 0..62 {
|
||||
let pos = stream.len();
|
||||
let bytes_written = $write_fn_name(&mut stream, pos, (3u64 << x) as $int_ty);
|
||||
assert_eq!(stream.len(), pos + bytes_written);
|
||||
$write_fn_name(&mut stream, (3u64 << x) as $int_ty);
|
||||
}
|
||||
|
||||
let mut position = 0;
|
||||
@ -195,9 +181,7 @@ fn test_signed_leb128() {
|
||||
let values: Vec<_> = (-500..500).map(|i| i * 0x12345789ABCDEF).collect();
|
||||
let mut stream = Vec::new();
|
||||
for &x in &values {
|
||||
let pos = stream.len();
|
||||
let bytes_written = write_signed_leb128(&mut stream, pos, x);
|
||||
assert_eq!(stream.len(), pos + bytes_written);
|
||||
write_signed_leb128(&mut stream, x);
|
||||
}
|
||||
let mut pos = 0;
|
||||
for &x in &values {
|
||||
|
@ -23,6 +23,7 @@ Core encoding and decoding interfaces.
|
||||
#![feature(box_syntax)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(specialization)]
|
||||
#![feature(never_type)]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
|
||||
pub use self::serialize::{Decoder, Encoder, Decodable, Encodable};
|
||||
|
@ -10,50 +10,48 @@
|
||||
|
||||
use leb128::{self, read_signed_leb128, write_signed_leb128};
|
||||
use std::borrow::Cow;
|
||||
use std::io::{self, Write};
|
||||
use serialize;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Encoder
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub type EncodeResult = io::Result<()>;
|
||||
pub type EncodeResult = Result<(), !>;
|
||||
|
||||
pub struct Encoder<'a> {
|
||||
pub cursor: &'a mut io::Cursor<Vec<u8>>,
|
||||
pub struct Encoder {
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<'a> Encoder<'a> {
|
||||
pub fn new(cursor: &'a mut io::Cursor<Vec<u8>>) -> Encoder<'a> {
|
||||
Encoder { cursor: cursor }
|
||||
impl Encoder {
|
||||
pub fn new(data: Vec<u8>) -> Encoder {
|
||||
Encoder { data }
|
||||
}
|
||||
|
||||
pub fn emit_raw_bytes(&mut self, s: &[u8]) -> EncodeResult {
|
||||
self.cursor.write_all(s)
|
||||
pub fn into_inner(self) -> Vec<u8> {
|
||||
self.data
|
||||
}
|
||||
|
||||
pub fn emit_raw_bytes(&mut self, s: &[u8]) {
|
||||
self.data.extend_from_slice(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
macro_rules! write_uleb128 {
|
||||
($enc:expr, $value:expr, $fun:ident) => {{
|
||||
let pos = $enc.cursor.position() as usize;
|
||||
let bytes_written = leb128::$fun($enc.cursor.get_mut(), pos, $value);
|
||||
$enc.cursor.set_position((pos + bytes_written) as u64);
|
||||
leb128::$fun(&mut $enc.data, $value);
|
||||
Ok(())
|
||||
}}
|
||||
}
|
||||
|
||||
macro_rules! write_sleb128 {
|
||||
($enc:expr, $value:expr) => {{
|
||||
let pos = $enc.cursor.position() as usize;
|
||||
let bytes_written = write_signed_leb128($enc.cursor.get_mut(), pos, $value as i128);
|
||||
$enc.cursor.set_position((pos + bytes_written) as u64);
|
||||
write_signed_leb128(&mut $enc.data, $value as i128);
|
||||
Ok(())
|
||||
}}
|
||||
}
|
||||
|
||||
impl<'a> serialize::Encoder for Encoder<'a> {
|
||||
type Error = io::Error;
|
||||
impl serialize::Encoder for Encoder {
|
||||
type Error = !;
|
||||
|
||||
#[inline]
|
||||
fn emit_nil(&mut self) -> EncodeResult {
|
||||
@ -87,9 +85,7 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
||||
|
||||
#[inline]
|
||||
fn emit_u8(&mut self, v: u8) -> EncodeResult {
|
||||
let pos = self.cursor.position() as usize;
|
||||
leb128::write_to_vec(self.cursor.get_mut(), pos, v);
|
||||
self.cursor.set_position((pos + 1) as u64);
|
||||
self.data.push(v);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -153,15 +149,15 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
||||
#[inline]
|
||||
fn emit_str(&mut self, v: &str) -> EncodeResult {
|
||||
self.emit_usize(v.len())?;
|
||||
let _ = self.cursor.write_all(v.as_bytes());
|
||||
self.emit_raw_bytes(v.as_bytes());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Encoder<'a> {
|
||||
impl Encoder {
|
||||
#[inline]
|
||||
pub fn position(&self) -> usize {
|
||||
self.cursor.position() as usize
|
||||
self.data.len()
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,7 +335,6 @@ impl<'a> serialize::Decoder for Decoder<'a> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serialize::{Encodable, Decodable};
|
||||
use std::io::Cursor;
|
||||
use std::fmt::Debug;
|
||||
use super::{Encoder, Decoder};
|
||||
|
||||
@ -368,14 +363,13 @@ mod tests {
|
||||
|
||||
|
||||
fn check_round_trip<T: Encodable + Decodable + PartialEq + Debug>(values: Vec<T>) {
|
||||
let mut cursor = Cursor::new(Vec::new());
|
||||
let mut encoder = Encoder::new(Vec::new());
|
||||
|
||||
for value in &values {
|
||||
let mut encoder = Encoder::new(&mut cursor);
|
||||
Encodable::encode(&value, &mut encoder).unwrap();
|
||||
}
|
||||
|
||||
let data = cursor.into_inner();
|
||||
let data = encoder.into_inner();
|
||||
let mut decoder = Decoder::new(&data[..], 0);
|
||||
|
||||
for value in values {
|
||||
|
@ -41,17 +41,16 @@ enum WireProtocol {
|
||||
fn encode_json<T: Encodable>(val: &T, wr: &mut Cursor<Vec<u8>>) {
|
||||
write!(wr, "{}", json::as_json(val));
|
||||
}
|
||||
fn encode_opaque<T: Encodable>(val: &T, wr: &mut Cursor<Vec<u8>>) {
|
||||
fn encode_opaque<T: Encodable>(val: &T, wr: Vec<u8>) {
|
||||
let mut encoder = opaque::Encoder::new(wr);
|
||||
val.encode(&mut encoder);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let target = Foo{baz: false,};
|
||||
let mut wr = Cursor::new(Vec::new());
|
||||
let proto = WireProtocol::JSON;
|
||||
match proto {
|
||||
WireProtocol::JSON => encode_json(&target, &mut wr),
|
||||
WireProtocol::Opaque => encode_opaque(&target, &mut wr)
|
||||
WireProtocol::JSON => encode_json(&target, &mut Cursor::new(Vec::new())),
|
||||
WireProtocol::Opaque => encode_opaque(&target, Vec::new())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user