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