1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use crate::{
input::{Input, TreasuryInput},
output::{Output, TreasuryOutput},
protocol::ProtocolParameters,
Error,
};
#[derive(Clone, Debug, Eq, PartialEq, packable::Packable)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[packable(unpack_visitor = ProtocolParameters)]
pub struct TreasuryTransactionPayload {
#[packable(verify_with = verify_input)]
input: Input,
#[packable(verify_with = verify_output)]
output: Output,
}
impl TreasuryTransactionPayload {
pub const KIND: u32 = 4;
pub fn new(input: TreasuryInput, output: TreasuryOutput) -> Result<Self, Error> {
Ok(Self {
input: input.into(),
output: output.into(),
})
}
pub fn input(&self) -> &TreasuryInput {
if let Input::Treasury(ref input) = self.input {
input
} else {
unreachable!()
}
}
pub fn output(&self) -> &TreasuryOutput {
if let Output::Treasury(ref output) = self.output {
output
} else {
unreachable!()
}
}
}
fn verify_input<const VERIFY: bool>(input: &Input, _: &ProtocolParameters) -> Result<(), Error> {
if VERIFY && !matches!(input, Input::Treasury(_)) {
Err(Error::InvalidInputKind(input.kind()))
} else {
Ok(())
}
}
fn verify_output<const VERIFY: bool>(output: &Output, _: &ProtocolParameters) -> Result<(), Error> {
if VERIFY && !matches!(output, Output::Treasury(_)) {
Err(Error::InvalidOutputKind(output.kind()))
} else {
Ok(())
}
}
#[cfg(feature = "dto")]
#[allow(missing_docs)]
pub mod dto {
use serde::{Deserialize, Serialize};
use super::*;
use crate::{
error::dto::DtoError,
input::dto::{InputDto, TreasuryInputDto},
output::dto::{OutputDto, TreasuryOutputDto},
};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct TreasuryTransactionPayloadDto {
#[serde(rename = "type")]
pub kind: u32,
pub input: InputDto,
pub output: OutputDto,
}
impl From<&TreasuryTransactionPayload> for TreasuryTransactionPayloadDto {
fn from(value: &TreasuryTransactionPayload) -> Self {
TreasuryTransactionPayloadDto {
kind: TreasuryTransactionPayload::KIND,
input: InputDto::Treasury(TreasuryInputDto::from(value.input())),
output: OutputDto::Treasury(TreasuryOutputDto::from(value.output())),
}
}
}
impl TreasuryTransactionPayload {
pub fn try_from_dto(
value: &TreasuryTransactionPayloadDto,
token_supply: u64,
) -> Result<TreasuryTransactionPayload, DtoError> {
Ok(TreasuryTransactionPayload::new(
if let InputDto::Treasury(ref input) = value.input {
input.try_into()?
} else {
return Err(DtoError::InvalidField("input"));
},
if let OutputDto::Treasury(ref output) = value.output {
TreasuryOutput::try_from_dto(output, token_supply)?
} else {
return Err(DtoError::InvalidField("output"));
},
)?)
}
}
}