1use af_sui_types::TypeTag;
2use derive_more::{Deref, DerefMut, From, Into};
3use derive_where::derive_where;
4use serde::{Deserialize, Serialize};
5
6use crate::{MoveType, ParseTypeTagError, StaticTypeTag, TypeTagError};
7
8#[derive(
9 Clone, Debug, Deref, DerefMut, Deserialize, From, Into, Serialize, PartialEq, Eq, Hash,
10)]
11#[serde(bound(deserialize = ""))]
12pub struct MoveVec<T: MoveType>(Vec<T>);
13
14impl<T: MoveType> MoveType for MoveVec<T> {
15 type TypeTag = VecTypeTag<T>;
16}
17
18impl<T: StaticTypeTag> StaticTypeTag for MoveVec<T> {
19 fn type_() -> Self::TypeTag {
20 VecTypeTag(T::type_())
21 }
22}
23
24impl<T: MoveType> std::fmt::Display for MoveVec<T> {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 use tabled::settings::style::Style;
27 use tabled::settings::{Rotate, Settings};
28 use tabled::Table;
29
30 let mut table = Table::from_iter([self.iter().map(|e| e.to_string())]);
31 let settings = Settings::default()
32 .with(Rotate::Right)
33 .with(Style::rounded().remove_horizontals());
34 table.with(settings);
35 write!(f, "{table}")
36 }
37}
38
39impl<T: MoveType> std::fmt::Display for crate::MoveInstance<MoveVec<T>> {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 write!(f, "{}", self.value)
42 }
43}
44
45#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
46#[derive_where(PartialOrd, Ord)]
47pub struct VecTypeTag<T: MoveType>(T::TypeTag);
48
49impl<T: MoveType> From<VecTypeTag<T>> for TypeTag {
50 fn from(value: VecTypeTag<T>) -> Self {
51 Self::Vector(Box::new(value.0.into()))
52 }
53}
54
55impl<T: MoveType> TryFrom<TypeTag> for VecTypeTag<T> {
56 type Error = TypeTagError;
57
58 fn try_from(value: TypeTag) -> Result<Self, Self::Error> {
59 match value {
60 TypeTag::Vector(type_) => Ok(Self((*type_).try_into()?)),
61 _ => Err(TypeTagError::Variant {
62 expected: "Vector(_)".to_owned(),
63 got: value,
64 }),
65 }
66 }
67}
68
69impl<T: MoveType> std::str::FromStr for VecTypeTag<T> {
70 type Err = ParseTypeTagError;
71
72 fn from_str(s: &str) -> Result<Self, Self::Err> {
73 let tag: TypeTag = s.parse()?;
74 Ok(tag.try_into()?)
75 }
76}