Move finish
out of the Encoder
trait.
This simplifies things, but requires making `CacheEncoder` non-generic. (This was previously merged as commit 4 in #94732 and then was reverted in #97905 because it caused a perf regression.)
This commit is contained in:
parent
ca983054e1
commit
bb02cc47c4
13 changed files with 51 additions and 111 deletions
|
@ -24,6 +24,10 @@ impl MemEncoder {
|
|||
pub fn position(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
|
||||
pub fn finish(self) -> Vec<u8> {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! write_leb128 {
|
||||
|
@ -54,9 +58,6 @@ macro_rules! write_leb128 {
|
|||
const STR_SENTINEL: u8 = 0xC1;
|
||||
|
||||
impl Encoder for MemEncoder {
|
||||
type Ok = Vec<u8>;
|
||||
type Err = !;
|
||||
|
||||
#[inline]
|
||||
fn emit_usize(&mut self, v: usize) {
|
||||
write_leb128!(self, v, usize, write_usize_leb128)
|
||||
|
@ -150,10 +151,6 @@ impl Encoder for MemEncoder {
|
|||
fn emit_raw_bytes(&mut self, s: &[u8]) {
|
||||
self.data.extend_from_slice(s);
|
||||
}
|
||||
|
||||
fn finish(self) -> Result<Self::Ok, Self::Err> {
|
||||
Ok(self.data)
|
||||
}
|
||||
}
|
||||
|
||||
pub type FileEncodeResult = Result<usize, io::Error>;
|
||||
|
@ -389,6 +386,13 @@ impl FileEncoder {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish(mut self) -> Result<usize, io::Error> {
|
||||
self.flush();
|
||||
|
||||
let res = std::mem::replace(&mut self.res, Ok(()));
|
||||
res.map(|()| self.position())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for FileEncoder {
|
||||
|
@ -426,9 +430,6 @@ macro_rules! file_encoder_write_leb128 {
|
|||
}
|
||||
|
||||
impl Encoder for FileEncoder {
|
||||
type Ok = usize;
|
||||
type Err = io::Error;
|
||||
|
||||
#[inline]
|
||||
fn emit_usize(&mut self, v: usize) {
|
||||
file_encoder_write_leb128!(self, v, usize, write_usize_leb128)
|
||||
|
@ -522,13 +523,6 @@ impl Encoder for FileEncoder {
|
|||
fn emit_raw_bytes(&mut self, s: &[u8]) {
|
||||
self.write_all(s);
|
||||
}
|
||||
|
||||
fn finish(mut self) -> Result<usize, io::Error> {
|
||||
self.flush();
|
||||
|
||||
let res = std::mem::replace(&mut self.res, Ok(()));
|
||||
res.map(|()| self.position())
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -18,13 +18,10 @@ use std::sync::Arc;
|
|||
/// is pervasive and has non-trivial cost. Instead, impls of this trait must
|
||||
/// implement a delayed error handling strategy. If a failure occurs, they
|
||||
/// should record this internally, and all subsequent encoding operations can
|
||||
/// be processed or ignored, whichever is appropriate. Then when `finish()` is
|
||||
/// called, an error result should be returned to indicate the failure. If no
|
||||
/// failures occurred, then `finish()` should return a success result.
|
||||
/// be processed or ignored, whichever is appropriate. Then they should provide
|
||||
/// a `finish` method that finishes up encoding. If the encoder is fallible,
|
||||
/// `finish` should return a `Result` that indicates success or failure.
|
||||
pub trait Encoder {
|
||||
type Ok;
|
||||
type Err;
|
||||
|
||||
// Primitive types:
|
||||
fn emit_usize(&mut self, v: usize);
|
||||
fn emit_u128(&mut self, v: u128);
|
||||
|
@ -64,9 +61,6 @@ pub trait Encoder {
|
|||
fn emit_fieldless_enum_variant<const ID: usize>(&mut self) {
|
||||
self.emit_usize(ID)
|
||||
}
|
||||
|
||||
// Consume the encoder, getting the result.
|
||||
fn finish(self) -> Result<Self::Ok, Self::Err>;
|
||||
}
|
||||
|
||||
// Note: all the methods in this trait are infallible, which may be surprising.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
use rustc_serialize::opaque::{MemDecoder, MemEncoder};
|
||||
use rustc_serialize::{Decodable, Encodable, Encoder as EncoderTrait};
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, Encodable, Decodable)]
|
||||
|
@ -38,7 +38,7 @@ fn check_round_trip<
|
|||
Encodable::encode(value, &mut encoder);
|
||||
}
|
||||
|
||||
let data = encoder.finish().unwrap();
|
||||
let data = encoder.finish();
|
||||
let mut decoder = MemDecoder::new(&data[..], 0);
|
||||
|
||||
for value in values {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue