cashweb_bitcoin/transaction/
output.rs1use bytes::{Buf, BufMut};
5use thiserror::Error;
6
7use super::script::Script;
8use crate::{
9 var_int::{DecodeError as VarIntDecodeError, VarInt},
10 Decodable, Encodable,
11};
12
13#[derive(Clone, Debug, PartialEq, Eq, Error)]
15pub enum DecodeError {
16 #[error("value too short")]
18 ValueTooShort,
19 #[error("script length: {0}")]
21 ScriptLen(VarIntDecodeError),
22 #[error("script too short")]
24 ScriptTooShort,
25}
26
27#[derive(Clone, Debug, Default, PartialEq, Eq)]
29#[allow(missing_docs)]
30pub struct Output {
31 pub value: u64,
32 pub script: Script,
33}
34
35impl Encodable for Output {
36 #[inline]
37 fn encoded_len(&self) -> usize {
38 8 + self.script.len_varint().encoded_len() + self.script.encoded_len()
39 }
40
41 #[inline]
42 fn encode_raw<B: BufMut>(&self, buf: &mut B) {
43 buf.put_u64_le(self.value);
44 self.script.len_varint().encode_raw(buf);
45 self.script.encode_raw(buf);
46 }
47}
48
49impl Decodable for Output {
50 type Error = DecodeError;
51
52 #[inline]
53 fn decode<B: Buf>(buf: &mut B) -> Result<Self, Self::Error> {
54 if buf.remaining() < 8 {
56 return Err(Self::Error::ValueTooShort);
57 }
58 let value = buf.get_u64_le();
59
60 let script_len: u64 = VarInt::decode(buf).map_err(Self::Error::ScriptLen)?.into();
62 let script_len = script_len as usize;
63 if buf.remaining() < script_len {
64 return Err(Self::Error::ScriptTooShort);
65 }
66 let mut raw_script = vec![0; script_len];
67 buf.copy_to_slice(&mut raw_script);
68 let script = raw_script.into();
69 Ok(Output { value, script })
70 }
71}