Skip to main content

iota_types/block/input/
mod.rs

1// Copyright 2020-2023 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4mod treasury;
5mod utxo;
6
7use core::ops::RangeInclusive;
8
9use derive_more::From;
10
11pub use self::{treasury::TreasuryInput, utxo::UtxoInput};
12use crate::block::Error;
13
14/// The maximum number of inputs of a transaction.
15pub const INPUT_COUNT_MAX: u16 = 128;
16/// The range of valid numbers of inputs of a transaction.
17pub const INPUT_COUNT_RANGE: RangeInclusive<u16> = 1..=INPUT_COUNT_MAX; // [1..128]
18/// The maximum index of inputs of a transaction.
19pub const INPUT_INDEX_MAX: u16 = INPUT_COUNT_MAX - 1; // 127
20/// The range of valid indices of inputs of a transaction.
21pub const INPUT_INDEX_RANGE: RangeInclusive<u16> = 0..=INPUT_INDEX_MAX; // [0..127]
22
23/// A generic input supporting different input kinds.
24#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, From, packable::Packable)]
25#[cfg_attr(
26    feature = "serde",
27    derive(serde::Serialize, serde::Deserialize),
28    serde(tag = "type", content = "data")
29)]
30#[packable(unpack_error = Error)]
31#[packable(tag_type = u8, with_error = Error::InvalidInputKind)]
32pub enum Input {
33    /// A UTXO input.
34    #[packable(tag = UtxoInput::KIND)]
35    Utxo(UtxoInput),
36    /// A treasury input.
37    #[packable(tag = TreasuryInput::KIND)]
38    Treasury(TreasuryInput),
39}
40
41impl Input {
42    /// Returns the input kind of an `Input`.
43    pub fn kind(&self) -> u8 {
44        match self {
45            Self::Utxo(_) => UtxoInput::KIND,
46            Self::Treasury(_) => TreasuryInput::KIND,
47        }
48    }
49
50    /// Checks whether the input is a [`UtxoInput`].
51    pub fn is_utxo(&self) -> bool {
52        matches!(self, Self::Utxo(_))
53    }
54
55    /// Gets the input as an actual [`UtxoInput`].
56    /// PANIC: do not call on a non-utxo input.
57    pub fn as_utxo(&self) -> &UtxoInput {
58        if let Self::Utxo(input) = self {
59            input
60        } else {
61            panic!("as_utxo called on a non-utxo input");
62        }
63    }
64
65    /// Checks whether the input is a [`TreasuryInput`].
66    pub fn is_treasury(&self) -> bool {
67        matches!(self, Self::Treasury(_))
68    }
69
70    /// Gets the input as an actual [`TreasuryInput`].
71    /// PANIC: do not call on a non-treasury input.
72    pub fn as_treasury(&self) -> &TreasuryInput {
73        if let Self::Treasury(input) = self {
74            input
75        } else {
76            panic!("as_treasury called on a non-treasury input");
77        }
78    }
79}
80
81#[cfg(feature = "dto")]
82#[allow(missing_docs)]
83pub mod dto {
84    use serde::{Deserialize, Serialize};
85
86    use super::*;
87    pub use super::{treasury::dto::TreasuryInputDto, utxo::dto::UtxoInputDto};
88    use crate::block::error::dto::DtoError;
89
90    /// Describes all the different input types.
91    #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, From)]
92    #[serde(untagged)]
93    pub enum InputDto {
94        Utxo(UtxoInputDto),
95        Treasury(TreasuryInputDto),
96    }
97
98    impl From<&Input> for InputDto {
99        fn from(value: &Input) -> Self {
100            match value {
101                Input::Utxo(u) => Self::Utxo(u.into()),
102                Input::Treasury(t) => Self::Treasury(t.into()),
103            }
104        }
105    }
106
107    impl TryFrom<&InputDto> for Input {
108        type Error = DtoError;
109
110        fn try_from(value: &InputDto) -> Result<Self, Self::Error> {
111            match value {
112                InputDto::Utxo(u) => Ok(Self::Utxo(u.try_into()?)),
113                InputDto::Treasury(t) => Ok(Self::Treasury(t.try_into()?)),
114            }
115        }
116    }
117}