1use std::str::FromStr;
4
5use af_sui_types::TypeTag;
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8use crate::{MoveType, MoveTypeTag, ParseTypeTagError, TypeTagError};
9
10#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq, Hash)]
36pub struct AnyT {
37 dummy_field: bool,
38}
39
40impl AnyT {
41 pub fn new() -> Self {
42 Self::default()
43 }
44}
45
46impl std::fmt::Display for AnyT {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 write!(f, "AnyT")
49 }
50}
51
52#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
56pub struct AnyTTypeTag(pub TypeTag);
57
58impl From<AnyTTypeTag> for TypeTag {
59 fn from(value: AnyTTypeTag) -> Self {
60 value.0
61 }
62}
63
64impl TryFrom<TypeTag> for AnyTTypeTag {
65 type Error = TypeTagError;
66
67 fn try_from(value: TypeTag) -> Result<Self, Self::Error> {
68 Ok(Self(value))
69 }
70}
71
72impl MoveTypeTag for AnyTTypeTag {
73 fn matches(_tag: &TypeTag) -> bool {
74 true
75 }
76
77 fn matches_instance(&self, _tag: &TypeTag) -> bool {
78 true
79 }
80}
81
82impl FromStr for AnyTTypeTag {
83 type Err = ParseTypeTagError;
84
85 fn from_str(s: &str) -> Result<Self, Self::Err> {
86 let tag: TypeTag = s.parse()?;
87 Ok(Self(tag))
88 }
89}
90
91impl std::fmt::Display for AnyTTypeTag {
92 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93 write!(f, "{}", self.0)
94 }
95}
96
97impl Serialize for AnyTTypeTag {
98 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
99 ser.collect_str(&self.0)
100 }
101}
102
103impl<'de> Deserialize<'de> for AnyTTypeTag {
104 fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
105 use serde::de::Error as _;
106 let s = String::deserialize(de)?;
107 s.parse().map_err(D::Error::custom)
108 }
109}
110
111impl MoveType for AnyT {
112 type TypeTag = AnyTTypeTag;
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
122 fn accepts_phantom_paramed_struct_tag() {
123 let raw: TypeTag = "0x1::authority::AuthorityCap<0x1::authority::VENDOR<0x2::aftermath::AFTERMATH>, 0x1::authority::ASSISTANT>"
124 .parse()
125 .unwrap();
126 let wrapped = AnyTTypeTag::try_from(raw.clone()).unwrap();
127 let back: TypeTag = wrapped.into();
128 assert_eq!(back, raw);
129 }
130
131 #[test]
134 fn accepts_non_struct_type_tag() {
135 for raw in [TypeTag::U64, TypeTag::Bool, TypeTag::Address] {
136 let wrapped = AnyTTypeTag::try_from(raw.clone()).unwrap();
137 assert_eq!(TypeTag::from(wrapped), raw);
138 }
139 }
140
141 #[test]
143 fn display_fromstr_roundtrip() {
144 let raw: TypeTag = "0x1::a::B<0x2::c::D<0x3::e::F>>".parse().unwrap();
145 let wrapped = AnyTTypeTag(raw.clone());
146 let s = wrapped.to_string();
147 let parsed = AnyTTypeTag::from_str(&s).unwrap();
148 assert_eq!(parsed.0, raw);
149 }
150
151 #[test]
153 fn serde_roundtrip_json() {
154 let raw: TypeTag = "0x1::a::B<0x2::c::D<0x3::e::F>>".parse().unwrap();
155 let wrapped = AnyTTypeTag(raw.clone());
156 let json = serde_json::to_string(&wrapped).unwrap();
157 let back: AnyTTypeTag = serde_json::from_str(&json).unwrap();
158 assert_eq!(back.0, raw);
159 }
160}