+
+macro_rules! impl_consensus_ser {
+ ($bitcoin_type: ty) => {
+ impl Writeable for $bitcoin_type {
+ fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+ match self.consensus_encode(WriterWriteAdaptor(writer)) {
+ Ok(_) => Ok(()),
+ Err(e) => Err(e),
+ }
+ }
+ }
+
+ impl Readable for $bitcoin_type {
+ fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+ match consensus::encode::Decodable::consensus_decode(r) {
+ Ok(t) => Ok(t),
+ Err(consensus::encode::Error::Io(ref e)) if e.kind() == io::ErrorKind::UnexpectedEof => Err(DecodeError::ShortRead),
+ Err(consensus::encode::Error::Io(e)) => Err(DecodeError::Io(e.kind())),
+ Err(_) => Err(DecodeError::InvalidValue),
+ }
+ }
+ }
+ }
+}
+impl_consensus_ser!(Transaction);
+impl_consensus_ser!(TxOut);
+
+impl<T: Readable> Readable for Mutex<T> {
+ fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+ let t: T = Readable::read(r)?;
+ Ok(Mutex::new(t))
+ }
+}
+impl<T: Writeable> Writeable for Mutex<T> {
+ fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+ self.lock().unwrap().write(w)
+ }
+}
+
+impl<A: Readable, B: Readable> Readable for (A, B) {
+ fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+ let a: A = Readable::read(r)?;
+ let b: B = Readable::read(r)?;
+ Ok((a, b))
+ }
+}
+impl<A: Writeable, B: Writeable> Writeable for (A, B) {
+ fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+ self.0.write(w)?;
+ self.1.write(w)
+ }
+}
+
+impl<A: Readable, B: Readable, C: Readable> Readable for (A, B, C) {
+ fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+ let a: A = Readable::read(r)?;
+ let b: B = Readable::read(r)?;
+ let c: C = Readable::read(r)?;
+ Ok((a, b, c))
+ }
+}
+impl<A: Writeable, B: Writeable, C: Writeable> Writeable for (A, B, C) {
+ fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+ self.0.write(w)?;
+ self.1.write(w)?;
+ self.2.write(w)
+ }
+}
+
+impl Writeable for () {
+ fn write<W: Writer>(&self, _: &mut W) -> Result<(), io::Error> {
+ Ok(())
+ }
+}
+impl Readable for () {
+ fn read<R: Read>(_r: &mut R) -> Result<Self, DecodeError> {
+ Ok(())
+ }
+}
+
+impl Writeable for String {
+ #[inline]
+ fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+ (self.len() as u16).write(w)?;
+ w.write_all(self.as_bytes())
+ }
+}
+impl Readable for String {
+ #[inline]
+ fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+ let v: Vec<u8> = Readable::read(r)?;
+ let ret = String::from_utf8(v).map_err(|_| DecodeError::InvalidValue)?;
+ Ok(ret)
+ }
+}
+
+impl Writeable for Duration {
+ #[inline]
+ fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+ self.as_secs().write(w)?;
+ self.subsec_nanos().write(w)
+ }
+}
+impl Readable for Duration {
+ #[inline]
+ fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+ let secs = Readable::read(r)?;
+ let nanos = Readable::read(r)?;
+ Ok(Duration::new(secs, nanos))
+ }
+}