defuse_core/token_id/
nep141.rs1use std::{fmt, str::FromStr};
2
3use near_sdk::{AccountId, AccountIdRef, near};
4use serde_with::{DeserializeFromStr, SerializeDisplay};
5
6use crate::token_id::error::TokenIdError;
7
8#[cfg(any(feature = "arbitrary", test))]
9use arbitrary_with::{Arbitrary, As};
10#[cfg(any(feature = "arbitrary", test))]
11use defuse_near_utils::arbitrary::ArbitraryAccountId;
12
13#[cfg_attr(any(feature = "arbitrary", test), derive(Arbitrary))]
14#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, SerializeDisplay, DeserializeFromStr)]
15#[near(serializers = [borsh])]
16pub struct Nep141TokenId {
17 #[cfg_attr(
18 any(feature = "arbitrary", test),
19 arbitrary(with = As::<ArbitraryAccountId>::arbitrary),
20 )]
21 contract_id: AccountId,
22}
23
24impl Nep141TokenId {
25 pub const fn new(contract_id: AccountId) -> Self {
26 Self { contract_id }
27 }
28
29 pub fn contract_id(&self) -> &AccountIdRef {
30 self.contract_id.as_ref()
31 }
32
33 pub fn into_contract_id(self) -> AccountId {
34 self.contract_id
35 }
36}
37
38impl std::fmt::Debug for Nep141TokenId {
39 #[inline]
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 write!(f, "{}", self.contract_id())
42 }
43}
44
45impl std::fmt::Display for Nep141TokenId {
46 #[inline]
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 fmt::Debug::fmt(&self, f)
49 }
50}
51
52impl FromStr for Nep141TokenId {
53 type Err = TokenIdError;
54
55 fn from_str(data: &str) -> Result<Self, Self::Err> {
56 Ok(Self {
57 contract_id: data.parse()?,
58 })
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 use defuse_test_utils::random::make_arbitrary;
67 use rstest::rstest;
68
69 #[rstest]
70 #[trace]
71 fn display_from_str_roundtrip(#[from(make_arbitrary)] token_id: Nep141TokenId) {
72 let s = token_id.to_string();
73 let got: Nep141TokenId = s.parse().unwrap();
74 assert_eq!(got, token_id);
75 }
76}