bee_block/output/token_scheme/
simple.rs1use packable::{
5 error::{UnpackError, UnpackErrorExt},
6 packer::Packer,
7 unpacker::Unpacker,
8 Packable,
9};
10use primitive_types::U256;
11
12use crate::error::Error;
13
14#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct SimpleTokenScheme {
18 minted_tokens: U256,
20 melted_tokens: U256,
22 maximum_supply: U256,
24}
25
26impl SimpleTokenScheme {
27 pub const KIND: u8 = 0;
29
30 #[inline(always)]
32 pub fn new(minted_tokens: U256, melted_tokens: U256, maximum_supply: U256) -> Result<Self, Error> {
33 verify_supply(&minted_tokens, &melted_tokens, &maximum_supply)?;
34
35 Ok(Self {
36 minted_tokens,
37 melted_tokens,
38 maximum_supply,
39 })
40 }
41
42 #[inline(always)]
44 pub fn minted_tokens(&self) -> U256 {
45 self.minted_tokens
46 }
47
48 #[inline(always)]
50 pub fn melted_tokens(&self) -> U256 {
51 self.melted_tokens
52 }
53
54 #[inline(always)]
56 pub fn maximum_supply(&self) -> U256 {
57 self.maximum_supply
58 }
59
60 #[inline(always)]
62 pub fn circulating_supply(&self) -> U256 {
63 self.minted_tokens - self.melted_tokens
64 }
65}
66
67impl Packable for SimpleTokenScheme {
68 type UnpackError = Error;
69 type UnpackVisitor = ();
70
71 fn pack<P: Packer>(&self, packer: &mut P) -> Result<(), P::Error> {
72 self.minted_tokens.pack(packer)?;
73 self.melted_tokens.pack(packer)?;
74 self.maximum_supply.pack(packer)?;
75
76 Ok(())
77 }
78
79 fn unpack<U: Unpacker, const VERIFY: bool>(
80 unpacker: &mut U,
81 visitor: &Self::UnpackVisitor,
82 ) -> Result<Self, UnpackError<Self::UnpackError, U::Error>> {
83 let minted_tokens = U256::unpack::<_, VERIFY>(unpacker, visitor).coerce()?;
84 let melted_tokens = U256::unpack::<_, VERIFY>(unpacker, visitor).coerce()?;
85 let maximum_supply = U256::unpack::<_, VERIFY>(unpacker, visitor).coerce()?;
86
87 if VERIFY {
88 verify_supply(&minted_tokens, &melted_tokens, &maximum_supply).map_err(UnpackError::Packable)?;
89 }
90
91 Ok(Self {
92 minted_tokens,
93 melted_tokens,
94 maximum_supply,
95 })
96 }
97}
98
99#[inline]
100fn verify_supply(minted_tokens: &U256, melted_tokens: &U256, maximum_supply: &U256) -> Result<(), Error> {
101 if maximum_supply.is_zero() || melted_tokens > minted_tokens || minted_tokens - melted_tokens > *maximum_supply {
102 return Err(Error::InvalidFoundryOutputSupply {
103 minted: *minted_tokens,
104 melted: *melted_tokens,
105 max: *maximum_supply,
106 });
107 }
108
109 Ok(())
110}
111
112#[cfg(feature = "dto")]
113#[allow(missing_docs)]
114pub mod dto {
115 use serde::{Deserialize, Serialize};
116
117 use super::*;
118 use crate::{dto::U256Dto, error::dto::DtoError};
119
120 #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
122 pub struct SimpleTokenSchemeDto {
123 #[serde(rename = "type")]
124 pub kind: u8,
125 #[serde(rename = "mintedTokens")]
127 pub minted_tokens: U256Dto,
128 #[serde(rename = "meltedTokens")]
130 pub melted_tokens: U256Dto,
131 #[serde(rename = "maximumSupply")]
133 pub maximum_supply: U256Dto,
134 }
135
136 impl From<&SimpleTokenScheme> for SimpleTokenSchemeDto {
137 fn from(value: &SimpleTokenScheme) -> Self {
138 Self {
139 kind: SimpleTokenScheme::KIND,
140 minted_tokens: (&value.minted_tokens()).into(),
141 melted_tokens: (&value.melted_tokens()).into(),
142 maximum_supply: (&value.maximum_supply()).into(),
143 }
144 }
145 }
146
147 impl TryFrom<&SimpleTokenSchemeDto> for SimpleTokenScheme {
148 type Error = DtoError;
149
150 fn try_from(value: &SimpleTokenSchemeDto) -> Result<Self, Self::Error> {
151 Self::new(
152 U256::try_from(&value.minted_tokens).map_err(|_| DtoError::InvalidField("mintedTokens"))?,
153 U256::try_from(&value.melted_tokens).map_err(|_| DtoError::InvalidField("meltedTokens"))?,
154 U256::try_from(&value.maximum_supply).map_err(|_| DtoError::InvalidField("maximumSupply"))?,
155 )
156 .map_err(DtoError::Block)
157 }
158 }
159}