ibc_types_transfer/
acknowledgement.rs1use core::fmt::{Display, Error as FmtError, Formatter};
2
3use crate::prelude::*;
4
5pub const ACK_ERR_STR: &str = "error handling packet on destination chain: see events for details";
8
9pub const ACK_SUCCESS_B64: &str = "AQ==";
11
12#[cfg_attr(feature = "with_serde", derive(serde::Serialize, serde::Deserialize))]
13#[derive(Clone, Debug, PartialEq, Eq)]
14pub enum ConstAckSuccess {
15 #[cfg_attr(feature = "with_serde", serde(rename = "AQ=="))]
16 Success,
17}
18
19#[cfg_attr(feature = "with_serde", derive(serde::Serialize, serde::Deserialize))]
20#[derive(Clone, Debug, PartialEq, Eq)]
21pub enum TokenTransferAcknowledgement {
22 #[cfg_attr(feature = "with_serde", serde(rename = "result"))]
25 Success(ConstAckSuccess),
26 #[cfg_attr(feature = "with_serde", serde(rename = "error"))]
29 Error(String),
30}
31
32impl TokenTransferAcknowledgement {
33 pub fn success() -> Self {
34 Self::Success(ConstAckSuccess::Success)
35 }
36
37 pub fn is_successful(&self) -> bool {
38 matches!(self, TokenTransferAcknowledgement::Success(_))
39 }
40}
41
42impl Display for TokenTransferAcknowledgement {
43 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
44 match self {
45 TokenTransferAcknowledgement::Success(_) => write!(f, "{ACK_SUCCESS_B64}"),
46 TokenTransferAcknowledgement::Error(err_str) => write!(f, "{err_str}"),
47 }
48 }
49}
50
51impl From<TokenTransferAcknowledgement> for Vec<u8> {
52 fn from(ack: TokenTransferAcknowledgement) -> Self {
53 match ack {
56 TokenTransferAcknowledgement::Success(_) => r#"{"result":"AQ=="}"#.as_bytes().into(),
57 TokenTransferAcknowledgement::Error(s) => alloc::format!(r#"{{"error":"{s}"}}"#).into(),
58 }
59 }
60}
61
62#[cfg(test)]
63mod test {
64 use super::*;
65
66 #[cfg(feature = "with_serde")]
67 #[test]
68 fn test_ack_ser() {
69 use crate::alloc::borrow::ToOwned;
70 fn ser_json_assert_eq(ack: TokenTransferAcknowledgement, json_str: &str) {
71 let ser = serde_json::to_string(&ack).unwrap();
72 assert_eq!(ser, json_str)
73 }
74
75 ser_json_assert_eq(
76 TokenTransferAcknowledgement::success(),
77 r#"{"result":"AQ=="}"#,
78 );
79 ser_json_assert_eq(
80 TokenTransferAcknowledgement::Error(
81 "cannot unmarshal ICS-20 transfer packet data".to_owned(),
82 ),
83 r#"{"error":"cannot unmarshal ICS-20 transfer packet data"}"#,
84 );
85 }
86
87 #[cfg(feature = "with_serde")]
88 #[test]
89 fn test_ack_success_to_vec() {
90 let ack_success: Vec<u8> = TokenTransferAcknowledgement::success().into();
91
92 assert_eq!(ack_success, r#"{"result":"AQ=="}"#.as_bytes());
96 }
97
98 #[cfg(feature = "with_serde")]
99 #[test]
100 fn test_ack_error_to_vec() {
101 use crate::alloc::string::ToString;
102 let ack_error: Vec<u8> = TokenTransferAcknowledgement::Error(
103 "cannot unmarshal ICS-20 transfer packet data".to_string(),
104 )
105 .into();
106
107 assert_eq!(
111 ack_error,
112 r#"{"error":"cannot unmarshal ICS-20 transfer packet data"}"#.as_bytes()
113 );
114 }
115
116 #[cfg(feature = "with_serde")]
117 #[test]
118 fn test_ack_de() {
119 use crate::alloc::borrow::ToOwned;
120 fn de_json_assert_eq(json_str: &str, ack: TokenTransferAcknowledgement) {
121 let de = serde_json::from_str::<TokenTransferAcknowledgement>(json_str).unwrap();
122 assert_eq!(de, ack)
123 }
124
125 de_json_assert_eq(
126 r#"{"result":"AQ=="}"#,
127 TokenTransferAcknowledgement::success(),
128 );
129 de_json_assert_eq(
130 r#"{"error":"cannot unmarshal ICS-20 transfer packet data"}"#,
131 TokenTransferAcknowledgement::Error(
132 "cannot unmarshal ICS-20 transfer packet data".to_owned(),
133 ),
134 );
135
136 assert!(
137 serde_json::from_str::<TokenTransferAcknowledgement>(r#"{"result":"AQ="}"#).is_err()
138 );
139 assert!(
140 serde_json::from_str::<TokenTransferAcknowledgement>(r#"{"success":"AQ=="}"#).is_err()
141 );
142 }
143}