zebra_chain/transparent/
script.rs
1use std::{fmt, io};
4
5use hex::ToHex;
6
7use crate::serialization::{
8 zcash_serialize_bytes, SerializationError, ZcashDeserialize, ZcashSerialize,
9};
10
11#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
13#[cfg_attr(
14 any(test, feature = "proptest-impl"),
15 derive(proptest_derive::Arbitrary)
16)]
17pub struct Script(
18 #[serde(with = "hex")]
23 Vec<u8>,
24);
25
26impl Script {
27 pub fn new(raw_bytes: &[u8]) -> Self {
30 Script(raw_bytes.to_vec())
31 }
32
33 pub fn as_raw_bytes(&self) -> &[u8] {
41 &self.0
42 }
43}
44
45impl fmt::Display for Script {
46 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47 f.write_str(&self.encode_hex::<String>())
48 }
49}
50
51impl fmt::Debug for Script {
52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53 f.debug_tuple("Script")
54 .field(&hex::encode(&self.0))
55 .finish()
56 }
57}
58
59impl ToHex for &Script {
60 fn encode_hex<T: FromIterator<char>>(&self) -> T {
61 self.as_raw_bytes().encode_hex()
62 }
63
64 fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
65 self.as_raw_bytes().encode_hex_upper()
66 }
67}
68
69impl ToHex for Script {
70 fn encode_hex<T: FromIterator<char>>(&self) -> T {
71 (&self).encode_hex()
72 }
73
74 fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
75 (&self).encode_hex_upper()
76 }
77}
78
79impl ZcashSerialize for Script {
80 fn zcash_serialize<W: io::Write>(&self, writer: W) -> Result<(), io::Error> {
81 zcash_serialize_bytes(&self.0, writer)
82 }
83}
84
85impl ZcashDeserialize for Script {
86 fn zcash_deserialize<R: io::Read>(reader: R) -> Result<Self, SerializationError> {
87 Vec::zcash_deserialize(reader).map(Script)
88 }
89}
90
91#[cfg(test)]
92mod proptests {
93 use std::io::Cursor;
94
95 use proptest::prelude::*;
96
97 use super::*;
98
99 proptest! {
100 #[test]
101 fn script_roundtrip(script in any::<Script>()) {
102 let _init_guard = zebra_test::init();
103
104 let mut bytes = Cursor::new(Vec::new());
105 script.zcash_serialize(&mut bytes)?;
106
107 bytes.set_position(0);
108 let other_script = Script::zcash_deserialize(&mut bytes)?;
109
110 prop_assert_eq![script, other_script];
111 }
112 }
113}