cardano_sdk/cardano/
input.rs1use crate::{Hash, cbor, pallas};
6use anyhow::anyhow;
7use std::{fmt, str::FromStr, sync::Arc};
8
9#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
11#[repr(transparent)]
12pub struct Input(Arc<pallas::TransactionInput>);
13
14impl fmt::Display for Input {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 write!(f, "Input({}#{})", &self.0.transaction_id, self.0.index)
17 }
18}
19
20impl Input {
23 pub fn new(transaction_id: Hash<32>, output_index: u64) -> Self {
25 Self(Arc::new(pallas::TransactionInput {
26 transaction_id: pallas::Hash::from(transaction_id),
27 index: output_index,
28 }))
29 }
30}
31
32impl Input {
35 pub fn transaction_id(&self) -> Hash<32> {
36 Hash::from(self.0.transaction_id)
37 }
38
39 pub fn output_index(&self) -> u64 {
40 self.0.index
41 }
42}
43
44impl From<pallas::TransactionInput> for Input {
47 fn from(i: pallas::TransactionInput) -> Self {
48 Input(Arc::new(i))
49 }
50}
51
52impl FromStr for Input {
53 type Err = anyhow::Error;
54
55 fn from_str(s: &str) -> anyhow::Result<Self> {
56 let mut split = s.split("#");
57
58 let transaction_id = split.next().ok_or(anyhow!("missing transaction id"))?;
59
60 let index = split.next().ok_or(anyhow!("missing output index"))?;
61
62 if split.next().is_some() {
63 return Err(anyhow!("leftovers after output index"));
64 }
65
66 Ok(Self::new(
67 <Hash<32>>::try_from(transaction_id)?,
68 index.parse::<u64>()?,
69 ))
70 }
71}
72
73impl From<Input> for pallas::TransactionInput {
76 fn from(i: Input) -> Self {
77 Arc::unwrap_or_clone(i.0)
78 }
79}
80
81impl<C> cbor::Encode<C> for Input {
84 fn encode<W: cbor::encode::write::Write>(
85 &self,
86 e: &mut cbor::Encoder<W>,
87 ctx: &mut C,
88 ) -> Result<(), cbor::encode::Error<W::Error>> {
89 e.encode_with(self.0.as_ref(), ctx)?;
90 Ok(())
91 }
92}
93
94impl<'d, C> cbor::Decode<'d, C> for Input {
95 fn decode(d: &mut cbor::Decoder<'d>, ctx: &mut C) -> Result<Self, cbor::decode::Error> {
96 Ok(Self(Arc::new(d.decode_with(ctx)?)))
97 }
98}
99
100#[cfg(any(test, feature = "test-utils"))]
101pub mod tests {
102 use crate::{Input, any, hash};
103 use proptest::prelude::*;
104
105 #[test]
108 fn display_input() {
109 assert_eq!(
110 Input::new(
111 hash!("702206530b2e1566e90b3aec753bd0abbf397842bd5421e0c3d23ed10167b3ce"),
112 42,
113 )
114 .to_string(),
115 "Input(702206530b2e1566e90b3aec753bd0abbf397842bd5421e0c3d23ed10167b3ce#42)",
116 );
117 }
118
119 pub mod generators {
122 use super::*;
123
124 prop_compose! {
125 pub fn input()(id in any::hash32(), ix in any::<u64>()) -> Input {
126 Input::new(id, ix)
127 }
128 }
129 }
130}