hedera/token/
token_nft_info_query.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use hedera_proto::services;
4use hedera_proto::services::token_service_client::TokenServiceClient;
5use tonic::transport::Channel;
6
7use crate::ledger_id::RefLedgerId;
8use crate::query::{
9    AnyQueryData,
10    Query,
11    QueryExecute,
12    ToQueryProtobuf,
13};
14use crate::{
15    BoxGrpcFuture,
16    Error,
17    NftId,
18    ToProtobuf,
19    TokenNftInfo,
20    ValidateChecksums,
21};
22
23/// Gets info on an NFT for a given `TokenID` and serial number.
24pub type TokenNftInfoQuery = Query<TokenNftInfoQueryData>;
25
26#[derive(Clone, Default, Debug)]
27pub struct TokenNftInfoQueryData {
28    /// The ID of the NFT
29    nft_id: Option<NftId>,
30}
31
32impl From<TokenNftInfoQueryData> for AnyQueryData {
33    #[inline]
34    fn from(data: TokenNftInfoQueryData) -> Self {
35        Self::TokenNftInfo(data)
36    }
37}
38
39impl TokenNftInfoQuery {
40    /// Returns the ID of the NFT for which information is requested.
41    #[must_use]
42    pub fn get_nft_id(&self) -> Option<NftId> {
43        self.data.nft_id
44    }
45
46    /// Sets the ID of the NFT for which information is requested.
47    pub fn nft_id(&mut self, nft_id: impl Into<NftId>) -> &mut Self {
48        self.data.nft_id = Some(nft_id.into());
49        self
50    }
51}
52
53impl ToQueryProtobuf for TokenNftInfoQueryData {
54    fn to_query_protobuf(&self, header: services::QueryHeader) -> services::Query {
55        let nft_id = self.nft_id.to_protobuf();
56
57        services::Query {
58            query: Some(services::query::Query::TokenGetNftInfo(services::TokenGetNftInfoQuery {
59                header: Some(header),
60                nft_id,
61            })),
62        }
63    }
64}
65
66impl QueryExecute for TokenNftInfoQueryData {
67    type Response = TokenNftInfo;
68
69    fn execute(
70        &self,
71        channel: Channel,
72        request: services::Query,
73    ) -> BoxGrpcFuture<'_, services::Response> {
74        Box::pin(async { TokenServiceClient::new(channel).get_token_nft_info(request).await })
75    }
76}
77
78impl ValidateChecksums for TokenNftInfoQueryData {
79    fn validate_checksums(&self, ledger_id: &RefLedgerId) -> Result<(), Error> {
80        self.nft_id.validate_checksums(ledger_id)
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use expect_test::expect;
87
88    use crate::query::ToQueryProtobuf;
89    use crate::{
90        Hbar,
91        TokenId,
92        TokenNftInfoQuery,
93    };
94
95    #[test]
96    fn serialize() {
97        expect![[r#"
98            Query {
99                query: Some(
100                    TokenGetNftInfo(
101                        TokenGetNftInfoQuery {
102                            header: Some(
103                                QueryHeader {
104                                    payment: None,
105                                    response_type: AnswerOnly,
106                                },
107                            ),
108                            nft_id: Some(
109                                NftId {
110                                    token_id: Some(
111                                        TokenId {
112                                            shard_num: 0,
113                                            realm_num: 0,
114                                            token_num: 5005,
115                                        },
116                                    ),
117                                    serial_number: 101,
118                                },
119                            ),
120                        },
121                    ),
122                ),
123            }
124        "#]]
125        .assert_debug_eq(
126            &TokenNftInfoQuery::new()
127                .nft_id(TokenId::new(0, 0, 5005).nft(101))
128                .max_payment_amount(Hbar::from_tinybars(100_000))
129                .data
130                .to_query_protobuf(Default::default()),
131        )
132    }
133
134    #[test]
135    fn properties() {
136        let mut query = TokenNftInfoQuery::new();
137        query
138            .nft_id(TokenId::new(0, 0, 5005).nft(101))
139            .max_payment_amount(Hbar::from_tinybars(100_000));
140
141        assert_eq!(query.get_nft_id().unwrap().to_string(), "0.0.5005/101");
142    }
143}