defuse_token_id/
nep171.rs

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