freenet_stdlib/contract_interface/
contract.rs1use std::io::{Cursor, Read};
7
8use byteorder::{LittleEndian, ReadBytesExt};
9use serde::{Deserialize, Serialize};
10
11use crate::parameters::Parameters;
12
13use super::code::ContractCode;
14use super::key::{internal_fmt_key, ContractKey};
15
16#[derive(Debug, Serialize, Deserialize, Clone)]
19#[cfg_attr(
20 any(feature = "testing", all(test, any(unix, windows))),
21 derive(arbitrary::Arbitrary)
22)]
23pub struct Contract<'a> {
24 #[serde(borrow)]
25 pub parameters: Parameters<'a>,
26 #[serde(borrow)]
27 pub data: ContractCode<'a>,
28 key: ContractKey,
30}
31
32impl<'a> Contract<'a> {
33 pub fn new(contract: ContractCode<'a>, parameters: Parameters<'a>) -> Contract<'a> {
35 let key = ContractKey::from_params_and_code(¶meters, &contract);
36 Contract {
37 parameters,
38 data: contract,
39 key,
40 }
41 }
42
43 pub fn key(&self) -> &ContractKey {
45 &self.key
46 }
47
48 pub fn into_code(self) -> ContractCode<'a> {
50 self.data
51 }
52}
53
54impl TryFrom<Vec<u8>> for Contract<'static> {
55 type Error = std::io::Error;
56
57 fn try_from(data: Vec<u8>) -> Result<Self, Self::Error> {
58 let mut reader = Cursor::new(data);
59
60 let params_len = reader.read_u64::<LittleEndian>()?;
61 let mut params_buf = vec![0; params_len as usize];
62 reader.read_exact(&mut params_buf)?;
63 let parameters = Parameters::from(params_buf);
64
65 let contract_len = reader.read_u64::<LittleEndian>()?;
66 let mut contract_buf = vec![0; contract_len as usize];
67 reader.read_exact(&mut contract_buf)?;
68 let contract = ContractCode::from(contract_buf);
69
70 let key = ContractKey::from_params_and_code(¶meters, &contract);
71
72 Ok(Contract {
73 parameters,
74 data: contract,
75 key,
76 })
77 }
78}
79
80impl PartialEq for Contract<'_> {
81 fn eq(&self, other: &Self) -> bool {
82 self.key == other.key
83 }
84}
85
86impl Eq for Contract<'_> {}
87
88impl std::fmt::Display for Contract<'_> {
89 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 write!(f, "ContractSpec( key: ")?;
91 internal_fmt_key(&self.key, f)?;
92 let data: String = if self.data.data.len() > 8 {
93 self.data.data[..4]
94 .iter()
95 .map(|b| char::from(*b))
96 .chain("...".chars())
97 .chain(self.data.data[4..].iter().map(|b| char::from(*b)))
98 .collect()
99 } else {
100 self.data.data.iter().copied().map(char::from).collect()
101 };
102 write!(f, ", data: [{data}])")
103 }
104}