Refactor Readable trait (#3309)
Currently Writable accepts trait Write as a type parameter but Readable takes Read as a trait object, which is not symmetrical and also less performant. This PR changes Readable trait and all places where it's used
This commit is contained in:
@@ -132,7 +132,7 @@ pub struct HeaderEntry {
|
||||
}
|
||||
|
||||
impl Readable for HeaderEntry {
|
||||
fn read(reader: &mut dyn Reader) -> Result<HeaderEntry, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<HeaderEntry, ser::Error> {
|
||||
let hash = Hash::read(reader)?;
|
||||
let timestamp = reader.read_u64()?;
|
||||
let total_difficulty = Difficulty::read(reader)?;
|
||||
@@ -192,7 +192,7 @@ impl Writeable for HeaderVersion {
|
||||
}
|
||||
|
||||
impl Readable for HeaderVersion {
|
||||
fn read(reader: &mut dyn Reader) -> Result<HeaderVersion, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<HeaderVersion, ser::Error> {
|
||||
let version = reader.read_u16()?;
|
||||
Ok(HeaderVersion(version))
|
||||
}
|
||||
@@ -280,7 +280,7 @@ impl Writeable for BlockHeader {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_block_header(reader: &mut dyn Reader) -> Result<BlockHeader, ser::Error> {
|
||||
fn read_block_header<R: Reader>(reader: &mut R) -> Result<BlockHeader, ser::Error> {
|
||||
let version = HeaderVersion::read(reader)?;
|
||||
let (height, timestamp) = ser_multiread!(reader, read_u64, read_i64);
|
||||
let prev_hash = Hash::read(reader)?;
|
||||
@@ -316,7 +316,7 @@ fn read_block_header(reader: &mut dyn Reader) -> Result<BlockHeader, ser::Error>
|
||||
|
||||
/// Deserialization of a block header
|
||||
impl Readable for BlockHeader {
|
||||
fn read(reader: &mut dyn Reader) -> Result<BlockHeader, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<BlockHeader, ser::Error> {
|
||||
read_block_header(reader)
|
||||
}
|
||||
}
|
||||
@@ -413,7 +413,7 @@ pub struct UntrustedBlockHeader(BlockHeader);
|
||||
|
||||
/// Deserialization of an untrusted block header
|
||||
impl Readable for UntrustedBlockHeader {
|
||||
fn read(reader: &mut dyn Reader) -> Result<UntrustedBlockHeader, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<UntrustedBlockHeader, ser::Error> {
|
||||
let header = read_block_header(reader)?;
|
||||
if header.timestamp
|
||||
> Utc::now() + Duration::seconds(12 * (consensus::BLOCK_TIME_SEC as i64))
|
||||
@@ -490,7 +490,7 @@ impl Writeable for Block {
|
||||
/// Implementation of Readable for a block, defines how to read a full block
|
||||
/// from a binary stream.
|
||||
impl Readable for Block {
|
||||
fn read(reader: &mut dyn Reader) -> Result<Block, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Block, ser::Error> {
|
||||
let header = BlockHeader::read(reader)?;
|
||||
let body = TransactionBody::read(reader)?;
|
||||
Ok(Block { header, body })
|
||||
@@ -828,7 +828,7 @@ pub struct UntrustedBlock(Block);
|
||||
|
||||
/// Deserialization of an untrusted block header
|
||||
impl Readable for UntrustedBlock {
|
||||
fn read(reader: &mut dyn Reader) -> Result<UntrustedBlock, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<UntrustedBlock, ser::Error> {
|
||||
// we validate header here before parsing the body
|
||||
let header = UntrustedBlockHeader::read(reader)?;
|
||||
let body = TransactionBody::read(reader)?;
|
||||
|
||||
@@ -41,7 +41,7 @@ impl Writeable for BlockSums {
|
||||
}
|
||||
|
||||
impl Readable for BlockSums {
|
||||
fn read(reader: &mut dyn Reader) -> Result<BlockSums, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<BlockSums, ser::Error> {
|
||||
Ok(BlockSums {
|
||||
utxo_sum: Commitment::read(reader)?,
|
||||
kernel_sum: Commitment::read(reader)?,
|
||||
|
||||
@@ -82,7 +82,7 @@ impl CompactBlockBody {
|
||||
}
|
||||
|
||||
impl Readable for CompactBlockBody {
|
||||
fn read(reader: &mut dyn Reader) -> Result<CompactBlockBody, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<CompactBlockBody, ser::Error> {
|
||||
let (out_full_len, kern_full_len, kern_id_len) =
|
||||
ser_multiread!(reader, read_u64, read_u64, read_u64);
|
||||
|
||||
@@ -215,7 +215,7 @@ impl Writeable for CompactBlock {
|
||||
/// Implementation of Readable for a compact block, defines how to read a
|
||||
/// compact block from a binary stream.
|
||||
impl Readable for CompactBlock {
|
||||
fn read(reader: &mut dyn Reader) -> Result<CompactBlock, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<CompactBlock, ser::Error> {
|
||||
let header = BlockHeader::read(reader)?;
|
||||
let nonce = reader.read_u64()?;
|
||||
let body = CompactBlockBody::read(reader)?;
|
||||
@@ -241,7 +241,7 @@ pub struct UntrustedCompactBlock(CompactBlock);
|
||||
/// Implementation of Readable for an untrusted compact block, defines how to read a
|
||||
/// compact block from a binary stream.
|
||||
impl Readable for UntrustedCompactBlock {
|
||||
fn read(reader: &mut dyn Reader) -> Result<UntrustedCompactBlock, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<UntrustedCompactBlock, ser::Error> {
|
||||
let header = UntrustedBlockHeader::read(reader)?;
|
||||
let nonce = reader.read_u64()?;
|
||||
let body = CompactBlockBody::read(reader)?;
|
||||
|
||||
@@ -131,7 +131,7 @@ impl AsRef<[u8]> for Hash {
|
||||
}
|
||||
|
||||
impl Readable for Hash {
|
||||
fn read(reader: &mut dyn Reader) -> Result<Hash, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Hash, ser::Error> {
|
||||
let v = reader.read_fixed_bytes(32)?;
|
||||
let mut a = [0; 32];
|
||||
a.copy_from_slice(&v[..]);
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ impl AsRef<[u8]> for ShortId {
|
||||
}
|
||||
|
||||
impl Readable for ShortId {
|
||||
fn read(reader: &mut dyn Reader) -> Result<ShortId, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<ShortId, ser::Error> {
|
||||
let v = reader.read_fixed_bytes(SHORT_ID_SIZE)?;
|
||||
let mut a = [0; SHORT_ID_SIZE];
|
||||
a.copy_from_slice(&v[..]);
|
||||
|
||||
@@ -47,7 +47,7 @@ impl Writeable for MerkleProof {
|
||||
}
|
||||
|
||||
impl Readable for MerkleProof {
|
||||
fn read(reader: &mut dyn Reader) -> Result<MerkleProof, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<MerkleProof, ser::Error> {
|
||||
let mmr_size = reader.read_u64()?;
|
||||
let path_len = reader.read_u64()?;
|
||||
let mut path = Vec::with_capacity(path_len as usize);
|
||||
|
||||
@@ -133,7 +133,7 @@ impl KernelFeatures {
|
||||
// Always read feature byte, 8 bytes for fee and 8 bytes for lock height.
|
||||
// Fee and lock height may be unused for some kernel variants but we need
|
||||
// to read these bytes and verify they are 0 if unused.
|
||||
fn read_v1(reader: &mut dyn Reader) -> Result<KernelFeatures, ser::Error> {
|
||||
fn read_v1<R: Reader>(reader: &mut R) -> Result<KernelFeatures, ser::Error> {
|
||||
let feature_byte = reader.read_u8()?;
|
||||
let fee = reader.read_u64()?;
|
||||
let lock_height = reader.read_u64()?;
|
||||
@@ -164,7 +164,7 @@ impl KernelFeatures {
|
||||
|
||||
// V2 kernels only expect bytes specific to each variant.
|
||||
// Coinbase kernels have no associated fee and we do not serialize a fee for these.
|
||||
fn read_v2(reader: &mut dyn Reader) -> Result<KernelFeatures, ser::Error> {
|
||||
fn read_v2<R: Reader>(reader: &mut R) -> Result<KernelFeatures, ser::Error> {
|
||||
let features = match reader.read_u8()? {
|
||||
KernelFeatures::PLAIN_U8 => {
|
||||
let fee = reader.read_u64()?;
|
||||
@@ -202,7 +202,7 @@ impl Writeable for KernelFeatures {
|
||||
}
|
||||
|
||||
impl Readable for KernelFeatures {
|
||||
fn read(reader: &mut dyn Reader) -> Result<KernelFeatures, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<KernelFeatures, ser::Error> {
|
||||
match reader.protocol_version().value() {
|
||||
0..=1 => KernelFeatures::read_v1(reader),
|
||||
2..=ProtocolVersion::MAX => KernelFeatures::read_v2(reader),
|
||||
@@ -336,7 +336,7 @@ impl Writeable for TxKernel {
|
||||
}
|
||||
|
||||
impl Readable for TxKernel {
|
||||
fn read(reader: &mut dyn Reader) -> Result<TxKernel, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<TxKernel, ser::Error> {
|
||||
Ok(TxKernel {
|
||||
features: KernelFeatures::read(reader)?,
|
||||
excess: Commitment::read(reader)?,
|
||||
@@ -534,7 +534,7 @@ impl Writeable for TransactionBody {
|
||||
/// Implementation of Readable for a body, defines how to read a
|
||||
/// body from a binary stream.
|
||||
impl Readable for TransactionBody {
|
||||
fn read(reader: &mut dyn Reader) -> Result<TransactionBody, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<TransactionBody, ser::Error> {
|
||||
let (input_len, output_len, kernel_len) =
|
||||
ser_multiread!(reader, read_u64, read_u64, read_u64);
|
||||
|
||||
@@ -908,7 +908,7 @@ impl Writeable for Transaction {
|
||||
/// Implementation of Readable for a transaction, defines how to read a full
|
||||
/// transaction from a binary stream.
|
||||
impl Readable for Transaction {
|
||||
fn read(reader: &mut dyn Reader) -> Result<Transaction, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Transaction, ser::Error> {
|
||||
let offset = BlindingFactor::read(reader)?;
|
||||
let body = TransactionBody::read(reader)?;
|
||||
let tx = Transaction { offset, body };
|
||||
@@ -1294,7 +1294,7 @@ impl Writeable for Input {
|
||||
/// Implementation of Readable for a transaction Input, defines how to read
|
||||
/// an Input from a binary stream.
|
||||
impl Readable for Input {
|
||||
fn read(reader: &mut dyn Reader) -> Result<Input, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Input, ser::Error> {
|
||||
let features = OutputFeatures::read(reader)?;
|
||||
let commit = Commitment::read(reader)?;
|
||||
Ok(Input::new(features, commit))
|
||||
@@ -1352,7 +1352,7 @@ impl Writeable for OutputFeatures {
|
||||
}
|
||||
|
||||
impl Readable for OutputFeatures {
|
||||
fn read(reader: &mut dyn Reader) -> Result<OutputFeatures, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<OutputFeatures, ser::Error> {
|
||||
let features =
|
||||
OutputFeatures::from_u8(reader.read_u8()?).ok_or(ser::Error::CorruptedData)?;
|
||||
Ok(features)
|
||||
@@ -1410,7 +1410,7 @@ impl Writeable for Output {
|
||||
/// Implementation of Readable for a transaction Output, defines how to read
|
||||
/// an Output from a binary stream.
|
||||
impl Readable for Output {
|
||||
fn read(reader: &mut dyn Reader) -> Result<Output, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Output, ser::Error> {
|
||||
Ok(Output {
|
||||
features: OutputFeatures::read(reader)?,
|
||||
commit: Commitment::read(reader)?,
|
||||
@@ -1545,7 +1545,7 @@ impl Writeable for OutputIdentifier {
|
||||
}
|
||||
|
||||
impl Readable for OutputIdentifier {
|
||||
fn read(reader: &mut dyn Reader) -> Result<OutputIdentifier, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<OutputIdentifier, ser::Error> {
|
||||
Ok(OutputIdentifier {
|
||||
features: OutputFeatures::read(reader)?,
|
||||
commit: Commitment::read(reader)?,
|
||||
|
||||
@@ -150,7 +150,7 @@ impl Writeable for Difficulty {
|
||||
}
|
||||
|
||||
impl Readable for Difficulty {
|
||||
fn read(reader: &mut dyn Reader) -> Result<Difficulty, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Difficulty, ser::Error> {
|
||||
let data = reader.read_u64()?;
|
||||
Ok(Difficulty { num: data })
|
||||
}
|
||||
@@ -249,7 +249,7 @@ impl Writeable for ProofOfWork {
|
||||
}
|
||||
|
||||
impl Readable for ProofOfWork {
|
||||
fn read(reader: &mut dyn Reader) -> Result<ProofOfWork, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<ProofOfWork, ser::Error> {
|
||||
let total_difficulty = Difficulty::read(reader)?;
|
||||
let secondary_scaling = reader.read_u32()?;
|
||||
let nonce = reader.read_u64()?;
|
||||
@@ -425,7 +425,7 @@ fn read_number(bits: &[u8], bit_start: usize, bit_count: usize) -> u64 {
|
||||
}
|
||||
|
||||
impl Readable for Proof {
|
||||
fn read(reader: &mut dyn Reader) -> Result<Proof, ser::Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Proof, ser::Error> {
|
||||
let edge_bits = reader.read_u8()?;
|
||||
if edge_bits == 0 || edge_bits > 63 {
|
||||
return Err(ser::Error::CorruptedData);
|
||||
|
||||
+29
-27
@@ -224,17 +224,17 @@ pub trait Writeable {
|
||||
}
|
||||
|
||||
/// Reader that exposes an Iterator interface.
|
||||
pub struct IteratingReader<'a, T> {
|
||||
pub struct IteratingReader<'a, T, R: Reader> {
|
||||
count: u64,
|
||||
curr: u64,
|
||||
reader: &'a mut dyn Reader,
|
||||
reader: &'a mut R,
|
||||
_marker: marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'a, T> IteratingReader<'a, T> {
|
||||
impl<'a, T, R: Reader> IteratingReader<'a, T, R> {
|
||||
/// Constructor to create a new iterating reader for the provided underlying reader.
|
||||
/// Takes a count so we know how many to iterate over.
|
||||
pub fn new(reader: &'a mut dyn Reader, count: u64) -> IteratingReader<'a, T> {
|
||||
pub fn new(reader: &'a mut R, count: u64) -> Self {
|
||||
let curr = 0;
|
||||
IteratingReader {
|
||||
count,
|
||||
@@ -245,9 +245,10 @@ impl<'a, T> IteratingReader<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for IteratingReader<'a, T>
|
||||
impl<'a, T, R> Iterator for IteratingReader<'a, T, R>
|
||||
where
|
||||
T: Readable,
|
||||
R: Reader,
|
||||
{
|
||||
type Item = T;
|
||||
|
||||
@@ -261,9 +262,10 @@ where
|
||||
}
|
||||
|
||||
/// Reads multiple serialized items into a Vec.
|
||||
pub fn read_multi<T>(reader: &mut dyn Reader, count: u64) -> Result<Vec<T>, Error>
|
||||
pub fn read_multi<T, R>(reader: &mut R, count: u64) -> Result<Vec<T>, Error>
|
||||
where
|
||||
T: Readable,
|
||||
R: Reader,
|
||||
{
|
||||
// Very rudimentary check to ensure we do not overflow anything
|
||||
// attempting to read huge amounts of data.
|
||||
@@ -331,7 +333,7 @@ impl Writeable for ProtocolVersion {
|
||||
}
|
||||
|
||||
impl Readable for ProtocolVersion {
|
||||
fn read(reader: &mut dyn Reader) -> Result<ProtocolVersion, Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<ProtocolVersion, Error> {
|
||||
let version = reader.read_u32()?;
|
||||
Ok(ProtocolVersion(version))
|
||||
}
|
||||
@@ -345,12 +347,12 @@ where
|
||||
Self: Sized,
|
||||
{
|
||||
/// Reads the data necessary to this Readable from the provided reader
|
||||
fn read(reader: &mut dyn Reader) -> Result<Self, Error>;
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Self, Error>;
|
||||
}
|
||||
|
||||
/// Deserializes a Readable from any std::io::Read implementation.
|
||||
pub fn deserialize<T: Readable>(
|
||||
source: &mut dyn Read,
|
||||
pub fn deserialize<T: Readable, R: Read>(
|
||||
source: &mut R,
|
||||
version: ProtocolVersion,
|
||||
) -> Result<T, Error> {
|
||||
let mut reader = BinReader::new(source, version);
|
||||
@@ -358,7 +360,7 @@ pub fn deserialize<T: Readable>(
|
||||
}
|
||||
|
||||
/// Deserialize a Readable based on our default "local" protocol version.
|
||||
pub fn deserialize_default<T: Readable>(source: &mut dyn Read) -> Result<T, Error> {
|
||||
pub fn deserialize_default<T: Readable, R: Read>(source: &mut R) -> Result<T, Error> {
|
||||
deserialize(source, ProtocolVersion::local())
|
||||
}
|
||||
|
||||
@@ -386,14 +388,14 @@ pub fn ser_vec<W: Writeable>(thing: &W, version: ProtocolVersion) -> Result<Vec<
|
||||
}
|
||||
|
||||
/// Utility to read from a binary source
|
||||
pub struct BinReader<'a> {
|
||||
source: &'a mut dyn Read,
|
||||
pub struct BinReader<'a, R: Read> {
|
||||
source: &'a mut R,
|
||||
version: ProtocolVersion,
|
||||
}
|
||||
|
||||
impl<'a> BinReader<'a> {
|
||||
impl<'a, R: Read> BinReader<'a, R> {
|
||||
/// Constructor for a new BinReader for the provided source and protocol version.
|
||||
pub fn new(source: &'a mut dyn Read, version: ProtocolVersion) -> BinReader<'a> {
|
||||
pub fn new(source: &'a mut R, version: ProtocolVersion) -> Self {
|
||||
BinReader { source, version }
|
||||
}
|
||||
}
|
||||
@@ -404,7 +406,7 @@ fn map_io_err(err: io::Error) -> Error {
|
||||
|
||||
/// Utility wrapper for an underlying byte Reader. Defines higher level methods
|
||||
/// to read numbers, byte vectors, hashes, etc.
|
||||
impl<'a> Reader for BinReader<'a> {
|
||||
impl<'a, R: Read> Reader for BinReader<'a, R> {
|
||||
fn read_u8(&mut self) -> Result<u8, Error> {
|
||||
self.source.read_u8().map_err(map_io_err)
|
||||
}
|
||||
@@ -544,7 +546,7 @@ impl<'a> Reader for StreamingReader<'a> {
|
||||
}
|
||||
|
||||
impl Readable for Commitment {
|
||||
fn read(reader: &mut dyn Reader) -> Result<Commitment, Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Commitment, Error> {
|
||||
let a = reader.read_fixed_bytes(PEDERSEN_COMMITMENT_SIZE)?;
|
||||
let mut c = [0; PEDERSEN_COMMITMENT_SIZE];
|
||||
c[..PEDERSEN_COMMITMENT_SIZE].clone_from_slice(&a[..PEDERSEN_COMMITMENT_SIZE]);
|
||||
@@ -565,7 +567,7 @@ impl Writeable for BlindingFactor {
|
||||
}
|
||||
|
||||
impl Readable for BlindingFactor {
|
||||
fn read(reader: &mut dyn Reader) -> Result<BlindingFactor, Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<BlindingFactor, Error> {
|
||||
let bytes = reader.read_fixed_bytes(SECRET_KEY_SIZE)?;
|
||||
Ok(BlindingFactor::from_slice(&bytes))
|
||||
}
|
||||
@@ -578,7 +580,7 @@ impl Writeable for Identifier {
|
||||
}
|
||||
|
||||
impl Readable for Identifier {
|
||||
fn read(reader: &mut dyn Reader) -> Result<Identifier, Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Identifier, Error> {
|
||||
let bytes = reader.read_fixed_bytes(IDENTIFIER_SIZE)?;
|
||||
Ok(Identifier::from_bytes(&bytes))
|
||||
}
|
||||
@@ -591,7 +593,7 @@ impl Writeable for RangeProof {
|
||||
}
|
||||
|
||||
impl Readable for RangeProof {
|
||||
fn read(reader: &mut dyn Reader) -> Result<RangeProof, Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<RangeProof, Error> {
|
||||
let len = reader.read_u64()?;
|
||||
let max_len = cmp::min(len as usize, MAX_PROOF_SIZE);
|
||||
let p = reader.read_fixed_bytes(max_len)?;
|
||||
@@ -618,7 +620,7 @@ impl PMMRable for RangeProof {
|
||||
}
|
||||
|
||||
impl Readable for Signature {
|
||||
fn read(reader: &mut dyn Reader) -> Result<Signature, Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Signature, Error> {
|
||||
let a = reader.read_fixed_bytes(AGG_SIGNATURE_SIZE)?;
|
||||
let mut c = [0; AGG_SIGNATURE_SIZE];
|
||||
c[..AGG_SIGNATURE_SIZE].clone_from_slice(&a[..AGG_SIGNATURE_SIZE]);
|
||||
@@ -643,7 +645,7 @@ impl Writeable for PublicKey {
|
||||
|
||||
impl Readable for PublicKey {
|
||||
// Read the public key in compressed form
|
||||
fn read(reader: &mut dyn Reader) -> Result<Self, Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Self, Error> {
|
||||
let buf = reader.read_fixed_bytes(COMPRESSED_PUBLIC_KEY_SIZE)?;
|
||||
let secp = Secp256k1::with_caps(ContextFlag::None);
|
||||
let pk = PublicKey::from_slice(&secp, &buf).map_err(|_| Error::CorruptedData)?;
|
||||
@@ -715,7 +717,7 @@ macro_rules! impl_int {
|
||||
}
|
||||
|
||||
impl Readable for $int {
|
||||
fn read(reader: &mut dyn Reader) -> Result<$int, Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<$int, Error> {
|
||||
reader.$r_fn()
|
||||
}
|
||||
}
|
||||
@@ -733,7 +735,7 @@ impl<T> Readable for Vec<T>
|
||||
where
|
||||
T: Readable,
|
||||
{
|
||||
fn read(reader: &mut dyn Reader) -> Result<Vec<T>, Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<Vec<T>, Error> {
|
||||
let mut buf = Vec::new();
|
||||
loop {
|
||||
let elem = T::read(reader);
|
||||
@@ -775,7 +777,7 @@ impl<A: Writeable, B: Writeable> Writeable for (A, B) {
|
||||
}
|
||||
|
||||
impl<A: Readable, B: Readable> Readable for (A, B) {
|
||||
fn read(reader: &mut dyn Reader) -> Result<(A, B), Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<(A, B), Error> {
|
||||
Ok((Readable::read(reader)?, Readable::read(reader)?))
|
||||
}
|
||||
}
|
||||
@@ -798,7 +800,7 @@ impl<A: Writeable, B: Writeable, C: Writeable, D: Writeable> Writeable for (A, B
|
||||
}
|
||||
|
||||
impl<A: Readable, B: Readable, C: Readable> Readable for (A, B, C) {
|
||||
fn read(reader: &mut dyn Reader) -> Result<(A, B, C), Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<(A, B, C), Error> {
|
||||
Ok((
|
||||
Readable::read(reader)?,
|
||||
Readable::read(reader)?,
|
||||
@@ -808,7 +810,7 @@ impl<A: Readable, B: Readable, C: Readable> Readable for (A, B, C) {
|
||||
}
|
||||
|
||||
impl<A: Readable, B: Readable, C: Readable, D: Readable> Readable for (A, B, C, D) {
|
||||
fn read(reader: &mut dyn Reader) -> Result<(A, B, C, D), Error> {
|
||||
fn read<R: Reader>(reader: &mut R) -> Result<(A, B, C, D), Error> {
|
||||
Ok((
|
||||
Readable::read(reader)?,
|
||||
Readable::read(reader)?,
|
||||
|
||||
Reference in New Issue
Block a user