use core::fmt::{Display, Error as FmtError, Formatter};
use crate::prelude::*;
pub const ACK_ERR_STR: &str = "error handling packet on destination chain: see events for details";
pub const ACK_SUCCESS_B64: &str = "AQ==";
#[cfg_attr(feature = "with_serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ConstAckSuccess {
#[cfg_attr(feature = "with_serde", serde(rename = "AQ=="))]
Success,
}
#[cfg_attr(feature = "with_serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum TokenTransferAcknowledgement {
#[cfg_attr(feature = "with_serde", serde(rename = "result"))]
Success(ConstAckSuccess),
#[cfg_attr(feature = "with_serde", serde(rename = "error"))]
Error(String),
}
impl TokenTransferAcknowledgement {
pub fn success() -> Self {
Self::Success(ConstAckSuccess::Success)
}
pub fn is_successful(&self) -> bool {
matches!(self, TokenTransferAcknowledgement::Success(_))
}
}
impl Display for TokenTransferAcknowledgement {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
TokenTransferAcknowledgement::Success(_) => write!(f, "{ACK_SUCCESS_B64}"),
TokenTransferAcknowledgement::Error(err_str) => write!(f, "{err_str}"),
}
}
}
impl From<TokenTransferAcknowledgement> for Vec<u8> {
fn from(ack: TokenTransferAcknowledgement) -> Self {
match ack {
TokenTransferAcknowledgement::Success(_) => r#"{"result":"AQ=="}"#.as_bytes().into(),
TokenTransferAcknowledgement::Error(s) => alloc::format!(r#"{{"error":"{s}"}}"#).into(),
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[cfg(feature = "with_serde")]
#[test]
fn test_ack_ser() {
use crate::alloc::borrow::ToOwned;
fn ser_json_assert_eq(ack: TokenTransferAcknowledgement, json_str: &str) {
let ser = serde_json::to_string(&ack).unwrap();
assert_eq!(ser, json_str)
}
ser_json_assert_eq(
TokenTransferAcknowledgement::success(),
r#"{"result":"AQ=="}"#,
);
ser_json_assert_eq(
TokenTransferAcknowledgement::Error(
"cannot unmarshal ICS-20 transfer packet data".to_owned(),
),
r#"{"error":"cannot unmarshal ICS-20 transfer packet data"}"#,
);
}
#[cfg(feature = "with_serde")]
#[test]
fn test_ack_success_to_vec() {
let ack_success: Vec<u8> = TokenTransferAcknowledgement::success().into();
assert_eq!(ack_success, r#"{"result":"AQ=="}"#.as_bytes());
}
#[cfg(feature = "with_serde")]
#[test]
fn test_ack_error_to_vec() {
use crate::alloc::string::ToString;
let ack_error: Vec<u8> = TokenTransferAcknowledgement::Error(
"cannot unmarshal ICS-20 transfer packet data".to_string(),
)
.into();
assert_eq!(
ack_error,
r#"{"error":"cannot unmarshal ICS-20 transfer packet data"}"#.as_bytes()
);
}
#[cfg(feature = "with_serde")]
#[test]
fn test_ack_de() {
use crate::alloc::borrow::ToOwned;
fn de_json_assert_eq(json_str: &str, ack: TokenTransferAcknowledgement) {
let de = serde_json::from_str::<TokenTransferAcknowledgement>(json_str).unwrap();
assert_eq!(de, ack)
}
de_json_assert_eq(
r#"{"result":"AQ=="}"#,
TokenTransferAcknowledgement::success(),
);
de_json_assert_eq(
r#"{"error":"cannot unmarshal ICS-20 transfer packet data"}"#,
TokenTransferAcknowledgement::Error(
"cannot unmarshal ICS-20 transfer packet data".to_owned(),
),
);
assert!(
serde_json::from_str::<TokenTransferAcknowledgement>(r#"{"result":"AQ="}"#).is_err()
);
assert!(
serde_json::from_str::<TokenTransferAcknowledgement>(r#"{"success":"AQ=="}"#).is_err()
);
}
}