1
Fork 0
This commit is contained in:
Nicholas Nethercote 2022-06-10 11:58:29 +10:00
parent 7f51a1b976
commit 3186e311e5
13 changed files with 111 additions and 51 deletions

View file

@ -24,10 +24,6 @@ impl Encoder {
pub fn position(&self) -> usize {
self.data.len()
}
pub fn finish(self) -> Vec<u8> {
self.data
}
}
macro_rules! write_leb128 {
@ -58,6 +54,9 @@ macro_rules! write_leb128 {
const STR_SENTINEL: u8 = 0xC1;
impl serialize::Encoder for Encoder {
type Ok = Vec<u8>;
type Err = !;
#[inline]
fn emit_usize(&mut self, v: usize) {
write_leb128!(self, v, usize, write_usize_leb128)
@ -151,6 +150,10 @@ impl serialize::Encoder for Encoder {
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>;
@ -386,13 +389,6 @@ 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 {
@ -430,6 +426,9 @@ macro_rules! file_encoder_write_leb128 {
}
impl serialize::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)
@ -523,6 +522,13 @@ impl serialize::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())
}
}
// -----------------------------------------------------------------------------

View file

@ -18,10 +18,13 @@ 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 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.
/// 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.
pub trait Encoder {
type Ok;
type Err;
// Primitive types:
fn emit_usize(&mut self, v: usize);
fn emit_u128(&mut self, v: u128);
@ -61,6 +64,9 @@ 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.