1use core::str::FromStr;
5
6use derive_more::{AsRef, Deref, From};
7
8use crate::{output::NftId, Error};
9
10#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, From, AsRef, Deref, packable::Packable)]
12#[as_ref(forward)]
13pub struct NftAddress(NftId);
14
15#[allow(clippy::len_without_is_empty)]
16impl NftAddress {
17 pub const KIND: u8 = 16;
19 pub const LENGTH: usize = NftId::LENGTH;
21
22 #[inline(always)]
24 pub fn new(id: NftId) -> Self {
25 Self::from(id)
26 }
27
28 #[inline(always)]
30 pub fn nft_id(&self) -> &NftId {
31 &self.0
32 }
33}
34
35#[cfg(feature = "serde")]
36string_serde_impl!(NftAddress);
37
38impl FromStr for NftAddress {
39 type Err = Error;
40
41 fn from_str(s: &str) -> Result<Self, Self::Err> {
42 Ok(NftAddress::from(NftId::from_str(s)?))
43 }
44}
45
46impl core::fmt::Display for NftAddress {
47 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
48 write!(f, "{}", self.0)
49 }
50}
51
52impl core::fmt::Debug for NftAddress {
53 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
54 write!(f, "NftAddress({})", self)
55 }
56}
57
58#[cfg(feature = "dto")]
59#[allow(missing_docs)]
60pub mod dto {
61 use serde::{Deserialize, Serialize};
62
63 use super::*;
64 use crate::error::dto::DtoError;
65
66 #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
68 pub struct NftAddressDto {
69 #[serde(rename = "type")]
70 pub kind: u8,
71 #[serde(rename = "nftId")]
72 pub nft_id: String,
73 }
74
75 impl From<&NftAddress> for NftAddressDto {
76 fn from(value: &NftAddress) -> Self {
77 Self {
78 kind: NftAddress::KIND,
79 nft_id: value.to_string(),
80 }
81 }
82 }
83
84 impl TryFrom<&NftAddressDto> for NftAddress {
85 type Error = DtoError;
86
87 fn try_from(value: &NftAddressDto) -> Result<Self, Self::Error> {
88 value
89 .nft_id
90 .parse::<NftAddress>()
91 .map_err(|_| DtoError::InvalidField("NFT address"))
92 }
93 }
94}