defuse_token_id/
nep171.rs

1pub use near_contract_standards::non_fungible_token::TokenId;
2
3use std::{fmt, str::FromStr};
4
5use near_sdk::{
6    AccountId, near,
7    serde_with::{DeserializeFromStr, SerializeDisplay},
8};
9
10use crate::{TokenIdError, TokenIdType};
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 Nep171TokenId {
17    pub contract_id: AccountId,
18
19    pub nft_token_id: TokenId,
20}
21
22impl Nep171TokenId {
23    pub fn new(contract_id: impl Into<AccountId>, nft_token_id: impl Into<TokenId>) -> Self {
24        Self {
25            contract_id: contract_id.into(),
26            nft_token_id: nft_token_id.into(),
27        }
28    }
29}
30
31impl std::fmt::Debug for Nep171TokenId {
32    #[inline]
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        write!(f, "{}:{}", &self.contract_id, &self.nft_token_id)
35    }
36}
37
38impl std::fmt::Display for Nep171TokenId {
39    #[inline]
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        fmt::Debug::fmt(&self, f)
42    }
43}
44
45impl FromStr for Nep171TokenId {
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<&Nep171TokenId> for TokenIdType {
57    #[inline]
58    fn from(_: &Nep171TokenId) -> Self {
59        Self::Nep171
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
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: Nep171TokenId) {
72        let s = token_id.to_string();
73        let got: Nep171TokenId = s.parse().unwrap();
74        assert_eq!(got, token_id);
75    }
76}