Remove unnecessary Cow

This commit is contained in:
Tony Garnock-Jones 2020-06-17 09:35:09 +02:00
parent 046a2ad999
commit b1c7fe8c04
3 changed files with 49 additions and 44 deletions

View File

@ -175,7 +175,7 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
-> Result<V::Value> where V: Visitor<'de> -> Result<V::Value> where V: Visitor<'de>
{ {
match super::value::magic::transmit_input_value( match super::value::magic::transmit_input_value(
name, || Ok(self.read.demand_next(false)?.into_owned()))? name, || Ok(self.read.demand_next(false)?))?
{ {
Some(v) => visitor.visit_u64(v), Some(v) => visitor.visit_u64(v),
None => { None => {

View File

@ -1,4 +1,3 @@
use std::borrow::Cow;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::reader::{self, Reader, BinaryReader}; use super::reader::{self, Reader, BinaryReader};
use super::value::IOValue; use super::value::IOValue;
@ -32,7 +31,7 @@ impl<'de, R: Reader<'de>> Decoder<'de, R> {
self.read_annotations = read_annotations self.read_annotations = read_annotations
} }
pub fn demand_next(&mut self) -> Result<Cow<'de, IOValue>> { pub fn demand_next(&mut self) -> Result<IOValue> {
self.read.demand_next(self.read_annotations) self.read.demand_next(self.read_annotations)
} }
} }
@ -43,7 +42,7 @@ impl<'de, R: Reader<'de>> std::iter::Iterator for Decoder<'de, R> {
match self.read.next(self.read_annotations) { match self.read.next(self.read_annotations) {
Err(e) => Some(Err(e)), Err(e) => Some(Err(e)),
Ok(None) => None, Ok(None) => None,
Ok(Some(v)) => Some(Ok(v.into_owned())), Ok(Some(v)) => Some(Ok(v)),
} }
} }
} }

View File

@ -65,7 +65,7 @@ impl CompoundBody {
{ {
match self.more_expected(read)? { match self.more_expected(read)? {
false => Ok(None), false => Ok(None),
true => Ok(Some(read.demand_next(read_annotations)?.into_owned())), true => Ok(Some(read.demand_next(read_annotations)?)),
} }
} }
@ -106,7 +106,7 @@ impl CompoundBody {
} }
pub trait Reader<'de> { pub trait Reader<'de> {
fn next(&mut self, read_annotations: bool) -> IOResult<Option<Cow<'de, IOValue>>>; fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>>;
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<CompoundBody>; fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<CompoundBody>;
fn open_sequence_or_set(&mut self) -> ReaderResult<CompoundBody>; fn open_sequence_or_set(&mut self) -> ReaderResult<CompoundBody>;
fn open_sequence(&mut self) -> ReaderResult<CompoundBody>; fn open_sequence(&mut self) -> ReaderResult<CompoundBody>;
@ -123,7 +123,7 @@ pub trait Reader<'de> {
Ok(()) Ok(())
} }
fn demand_next(&mut self, read_annotations: bool) -> IOResult<Cow<'de, IOValue>> { fn demand_next(&mut self, read_annotations: bool) -> IOResult<IOValue> {
match self.next(read_annotations)? { match self.next(read_annotations)? {
None => Err(io_eof()), None => Err(io_eof()),
Some(v) => Ok(v) Some(v) => Ok(v)
@ -189,7 +189,7 @@ pub trait Reader<'de> {
} }
impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R { impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R {
fn next(&mut self, read_annotations: bool) -> IOResult<Option<Cow<'de, IOValue>>> { fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> {
(*self).next(read_annotations) (*self).next(read_annotations)
} }
@ -374,7 +374,7 @@ impl<'de, S: BinarySource<'de>> BinaryReader<'de, S> {
fn expected(&mut self, k: ExpectedKind) -> error::Error { fn expected(&mut self, k: ExpectedKind) -> error::Error {
match self.demand_next(true) { match self.demand_next(true) {
Ok(v) => error::Error::Expected(k, Received::ReceivedOtherValue(v.into_owned())), Ok(v) => error::Error::Expected(k, Received::ReceivedOtherValue(v)),
Err(e) => e.into() Err(e) => e.into()
} }
} }
@ -568,7 +568,7 @@ impl<'de, S: BinarySource<'de>> BinaryReader<'de, S> {
} }
impl<'de, S: BinarySource<'de>> Reader<'de> for BinaryReader<'de, S> { impl<'de, S: BinarySource<'de>> Reader<'de> for BinaryReader<'de, S> {
fn next(&mut self, read_annotations: bool) -> IOResult<Option<Cow<'de, IOValue>>> { fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> {
match self.peek() { match self.peek() {
Err(e) if is_eof_io_error(&e) => return Ok(None), Err(e) if is_eof_io_error(&e) => return Ok(None),
Err(e) => return Err(e), Err(e) => return Err(e),
@ -576,26 +576,28 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for BinaryReader<'de, S> {
} }
loop { loop {
return Ok(Some(match decodeop(self.read()?)? { return Ok(Some(match decodeop(self.read()?)? {
(Op::Misc(0), 0) => Cow::Borrowed(&FALSE), (Op::Misc(0), 0) => FALSE.clone(),
(Op::Misc(0), 1) => Cow::Borrowed(&TRUE), (Op::Misc(0), 1) => TRUE.clone(),
(Op::Misc(0), 2) => { (Op::Misc(0), 2) => {
let bs: &[u8] = &self.readbytes(4)?; let mut bs = [0; 4];
Cow::Owned(Value::from(f32::from_bits(u32::from_be_bytes(bs.try_into().unwrap()))).wrap()) self.readbytes_into(&mut bs)?;
Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap()
} }
(Op::Misc(0), 3) => { (Op::Misc(0), 3) => {
let bs: &[u8] = &self.readbytes(8)?; let mut bs = [0; 8];
Cow::Owned(Value::from(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap()))).wrap()) self.readbytes_into(&mut bs)?;
Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap()
} }
(Op::Misc(0), 5) => { (Op::Misc(0), 5) => {
if read_annotations { if read_annotations {
let mut annotations = vec![self.demand_next(read_annotations)?.into_owned()]; let mut annotations = vec![self.demand_next(read_annotations)?];
while decodeop(self.peek()?)? == (Op::Misc(0), 5) { while decodeop(self.peek()?)? == (Op::Misc(0), 5) {
self.skip()?; self.skip()?;
annotations.push(self.demand_next(read_annotations)?.into_owned()); annotations.push(self.demand_next(read_annotations)?);
} }
let (existing_annotations, v) = self.demand_next(read_annotations)?.into_owned().pieces(); let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces();
annotations.extend_from_slice(existing_annotations.slice()); annotations.extend_from_slice(existing_annotations.slice());
Cow::Owned(IOValue::wrap(Annotations::new(Some(annotations)), v)) IOValue::wrap(Annotations::new(Some(annotations)), v)
} else { } else {
self.skip_value()?; self.skip_value()?;
continue; continue;
@ -605,41 +607,41 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for BinaryReader<'de, S> {
(Op::Misc(1), _) => Err(io_syntax_error("Invalid format A encoding"))?, (Op::Misc(1), _) => Err(io_syntax_error("Invalid format A encoding"))?,
(Op::Misc(2), arg) => match Op::try_from(arg)? { (Op::Misc(2), arg) => match Op::try_from(arg)? {
Op::Atom(minor) => Op::Atom(minor) =>
Cow::Owned(decodebinary(minor, Cow::Owned(self.gather_chunks()?))?), decodebinary(minor, Cow::Owned(self.gather_chunks()?))?,
Op::Compound(minor) => Cow::Owned(decodecompound(minor, DelimitedStream { Op::Compound(minor) => decodecompound(minor, DelimitedStream {
reader: ConfiguredBinaryReader { reader: ConfiguredBinaryReader {
reader: self, reader: self,
read_annotations, read_annotations,
phantom: PhantomData, phantom: PhantomData,
}, },
})?), })?,
_ => Err(io_syntax_error("Invalid format C start byte"))?, _ => Err(io_syntax_error("Invalid format C start byte"))?,
} }
(Op::Misc(3), arg) => { (Op::Misc(3), arg) => {
let n = if arg > 12 { i32::from(arg) - 16 } else { i32::from(arg) }; let n = if arg > 12 { i32::from(arg) - 16 } else { i32::from(arg) };
// TODO: prebuild these in value.rs // TODO: prebuild these in value.rs
Cow::Owned(Value::from(n).wrap()) Value::from(n).wrap()
} }
(Op::Misc(_), _) => unreachable!(), (Op::Misc(_), _) => unreachable!(),
(Op::Atom(AtomMinor::SignedInteger), arg) => { (Op::Atom(AtomMinor::SignedInteger), arg) => {
let count = self.wirelength(arg)?; let count = self.wirelength(arg)?;
let n = self.read_number_format_b(count)?; let n = self.read_number_format_b(count)?;
Cow::Owned(Value::SignedInteger(n).wrap()) Value::SignedInteger(n).wrap()
} }
(Op::Atom(minor), arg) => { (Op::Atom(minor), arg) => {
let count = self.wirelength(arg)?; let count = self.wirelength(arg)?;
Cow::Owned(decodebinary(minor, self.readbytes(count)?)?) decodebinary(minor, self.readbytes(count)?)?
} }
(Op::Compound(minor), arg) => { (Op::Compound(minor), arg) => {
let count = self.wirelength(arg)?; let count = self.wirelength(arg)?;
Cow::Owned(decodecompound(minor, CountedStream { decodecompound(minor, CountedStream {
reader: ConfiguredBinaryReader { reader: ConfiguredBinaryReader {
reader: self, reader: self,
read_annotations, read_annotations,
phantom: PhantomData, phantom: PhantomData,
}, },
count, count,
})?) })?
} }
(Op::Reserved(3), 15) => continue, (Op::Reserved(3), 15) => continue,
(Op::Reserved(_), _) => return Err(InvalidOp.into()), (Op::Reserved(_), _) => return Err(InvalidOp.into()),
@ -727,13 +729,15 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for BinaryReader<'de, S> {
match self.peek_next_nonannotation_op()? { match self.peek_next_nonannotation_op()? {
(Op::Misc(0), 2) => { (Op::Misc(0), 2) => {
self.skip()?; self.skip()?;
let bs: &[u8] = &self.readbytes(4)?; let mut bs = [0; 4];
Ok(f32::from_bits(u32::from_be_bytes(bs.try_into().unwrap()))) self.readbytes_into(&mut bs)?;
Ok(f32::from_bits(u32::from_be_bytes(bs)))
}, },
(Op::Misc(0), 3) => { (Op::Misc(0), 3) => {
self.skip()?; self.skip()?;
let bs: &[u8] = &self.readbytes(8)?; let mut bs = [0; 8];
Ok(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap())) as f32) self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs)) as f32)
}, },
_ => Err(self.expected(ExpectedKind::Float)), _ => Err(self.expected(ExpectedKind::Float)),
} }
@ -743,13 +747,15 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for BinaryReader<'de, S> {
match self.peek_next_nonannotation_op()? { match self.peek_next_nonannotation_op()? {
(Op::Misc(0), 2) => { (Op::Misc(0), 2) => {
self.skip()?; self.skip()?;
let bs: &[u8] = &self.readbytes(4)?; let mut bs = [0; 4];
Ok(f32::from_bits(u32::from_be_bytes(bs.try_into().unwrap())) as f64) self.readbytes_into(&mut bs)?;
Ok(f32::from_bits(u32::from_be_bytes(bs)) as f64)
}, },
(Op::Misc(0), 3) => { (Op::Misc(0), 3) => {
self.skip()?; self.skip()?;
let bs: &[u8] = &self.readbytes(8)?; let mut bs = [0; 8];
Ok(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap()))) self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs)))
}, },
_ => Err(self.expected(ExpectedKind::Double)), _ => Err(self.expected(ExpectedKind::Double)),
} }
@ -781,7 +787,7 @@ struct CountedStream<'de, 'a, S: BinarySource<'de>> {
impl<'de, 'a, S: BinarySource<'de>> Iterator for CountedStream<'de, 'a, S> impl<'de, 'a, S: BinarySource<'de>> Iterator for CountedStream<'de, 'a, S>
{ {
type Item = IOResult<Cow<'de, IOValue>>; type Item = IOResult<IOValue>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if self.count == 0 { return None } if self.count == 0 { return None }
self.count -= 1; self.count -= 1;
@ -795,7 +801,7 @@ struct DelimitedStream<'de, 'a, S: BinarySource<'de>> {
impl<'de, 'a, S: BinarySource<'de>> Iterator for DelimitedStream<'de, 'a, S> impl<'de, 'a, S: BinarySource<'de>> Iterator for DelimitedStream<'de, 'a, S>
{ {
type Item = IOResult<Cow<'de, IOValue>>; type Item = IOResult<IOValue>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
match self.reader.reader.peekend() { match self.reader.reader.peekend() {
Err(e) => Some(Err(e)), Err(e) => Some(Err(e)),
@ -827,7 +833,7 @@ pub fn decodebinary<'de>(minor: AtomMinor, bs: Cow<'de, [u8]>) -> IOResult<IOVal
}) })
} }
pub fn decodecompound<'de, I: Iterator<Item = IOResult<Cow<'de, IOValue>>>>( pub fn decodecompound<'de, I: Iterator<Item = IOResult<IOValue>>>(
minor: CompoundMinor, minor: CompoundMinor,
mut iter: I mut iter: I
) -> ) ->
@ -835,7 +841,7 @@ pub fn decodecompound<'de, I: Iterator<Item = IOResult<Cow<'de, IOValue>>>>(
{ {
match minor { match minor {
CompoundMinor::Record => { CompoundMinor::Record => {
let vs = iter.map(|r| r.map(|c| c.into_owned())).collect::<IOResult<Vec<IOValue>>>()?; let vs = iter.collect::<IOResult<Vec<IOValue>>>()?;
if vs.len() < 1 { if vs.len() < 1 {
Err(io_syntax_error("Too few elements in encoded record")) Err(io_syntax_error("Too few elements in encoded record"))
} else { } else {
@ -843,21 +849,21 @@ pub fn decodecompound<'de, I: Iterator<Item = IOResult<Cow<'de, IOValue>>>>(
} }
} }
CompoundMinor::Sequence => { CompoundMinor::Sequence => {
let vs = iter.map(|r| r.map(|c| c.into_owned())).collect::<IOResult<Vec<IOValue>>>()?; let vs = iter.collect::<IOResult<Vec<IOValue>>>()?;
Ok(Value::Sequence(vs).wrap()) Ok(Value::Sequence(vs).wrap())
} }
CompoundMinor::Set => { CompoundMinor::Set => {
let mut s = Set::new(); let mut s = Set::new();
for res in iter { s.insert(res?.into_owned()); } for res in iter { s.insert(res?); }
Ok(Value::Set(s).wrap()) Ok(Value::Set(s).wrap())
} }
CompoundMinor::Dictionary => { CompoundMinor::Dictionary => {
let mut d = Map::new(); let mut d = Map::new();
while let Some(kres) = iter.next() { while let Some(kres) = iter.next() {
let k = kres?.into_owned(); let k = kres?;
match iter.next() { match iter.next() {
Some(vres) => { Some(vres) => {
let v = vres?.into_owned(); let v = vres?;
d.insert(k, v); d.insert(k, v);
} }
None => return Err(io_syntax_error("Missing dictionary value")), None => return Err(io_syntax_error("Missing dictionary value")),