drt_sc/types/managed/wrapped/
token_identifier.rs1use alloc::string::ToString;
2
3use crate::{
4 abi::{TypeAbi, TypeAbiFrom, TypeName},
5 api::{ErrorApi, ErrorApiImpl, HandleConstraints, ManagedTypeApi, ManagedTypeApiImpl},
6 codec::*,
7 err_msg,
8 formatter::{FormatByteReceiver, SCDisplay, SCLowerHex},
9 types::{ManagedBuffer, ManagedType},
10};
11
12use super::RewaOrDcdtTokenIdentifier;
13
14#[repr(transparent)]
20#[derive(Clone)]
21pub struct TokenIdentifier<M: ErrorApi + ManagedTypeApi> {
22 buffer: ManagedBuffer<M>,
23}
24
25impl<M: ManagedTypeApi> ManagedType<M> for TokenIdentifier<M> {
26 type OwnHandle = M::ManagedBufferHandle;
27
28 #[inline]
29 fn from_handle(handle: M::ManagedBufferHandle) -> Self {
30 TokenIdentifier {
31 buffer: ManagedBuffer::from_handle(handle),
32 }
33 }
34
35 fn get_handle(&self) -> M::ManagedBufferHandle {
36 self.buffer.get_handle()
37 }
38
39 fn transmute_from_handle_ref(handle_ref: &M::ManagedBufferHandle) -> &Self {
40 unsafe { core::mem::transmute(handle_ref) }
41 }
42}
43
44impl<M: ManagedTypeApi> TokenIdentifier<M> {
45 #[inline]
46 pub fn from_dcdt_bytes<B: Into<ManagedBuffer<M>>>(bytes: B) -> Self {
47 TokenIdentifier {
48 buffer: bytes.into(),
49 }
50 }
51
52 #[inline]
53 pub fn into_managed_buffer(self) -> ManagedBuffer<M> {
54 self.buffer
55 }
56
57 #[inline]
58 pub fn as_managed_buffer(&self) -> &ManagedBuffer<M> {
59 &self.buffer
60 }
61
62 #[inline]
63 pub fn to_boxed_bytes(&self) -> crate::types::heap::BoxedBytes {
64 self.buffer.to_boxed_bytes()
65 }
66
67 pub fn is_valid_dcdt_identifier(&self) -> bool {
68 M::managed_type_impl().validate_token_identifier(self.buffer.handle.clone())
69 }
70
71 pub fn ticker(&self) -> ManagedBuffer<M> {
72 let token_id_len = self.buffer.len();
73 let ticker_len = M::managed_type_impl().get_token_ticker_len(token_id_len);
74 self.buffer.copy_slice(0, ticker_len).unwrap_or_else(|| {
75 M::error_api_impl().signal_error(err_msg::BAD_TOKEN_TICKER_FORMAT.as_bytes())
76 })
77 }
78}
79
80impl<M: ManagedTypeApi> From<ManagedBuffer<M>> for TokenIdentifier<M> {
81 #[inline]
82 fn from(buffer: ManagedBuffer<M>) -> Self {
83 TokenIdentifier { buffer }
84 }
85}
86
87impl<M: ManagedTypeApi> From<&[u8]> for TokenIdentifier<M> {
88 fn from(bytes: &[u8]) -> Self {
89 TokenIdentifier {
90 buffer: ManagedBuffer::new_from_bytes(bytes),
91 }
92 }
93}
94
95impl<M: ManagedTypeApi> From<&str> for TokenIdentifier<M> {
96 fn from(s: &str) -> Self {
97 TokenIdentifier::from(s.as_bytes())
98 }
99}
100
101impl<M: ManagedTypeApi> From<&crate::types::heap::String> for TokenIdentifier<M> {
102 fn from(s: &crate::types::heap::String) -> Self {
103 TokenIdentifier::from(s.as_bytes())
104 }
105}
106
107impl<M: ManagedTypeApi> PartialEq for TokenIdentifier<M> {
108 #[inline]
109 fn eq(&self, other: &Self) -> bool {
110 self.buffer == other.buffer
111 }
112}
113
114impl<M: ManagedTypeApi> Eq for TokenIdentifier<M> {}
115
116impl<M: ManagedTypeApi> PartialEq<RewaOrDcdtTokenIdentifier<M>> for TokenIdentifier<M> {
117 #[inline]
118 fn eq(&self, other: &RewaOrDcdtTokenIdentifier<M>) -> bool {
119 other.map_ref_or_else(
120 (),
121 |()| false,
122 |(), dcdt_token_identifier| dcdt_token_identifier == self,
123 )
124 }
125}
126
127impl<M: ManagedTypeApi> NestedEncode for TokenIdentifier<M> {
128 #[inline]
129 fn dep_encode_or_handle_err<O, H>(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr>
130 where
131 O: NestedEncodeOutput,
132 H: EncodeErrorHandler,
133 {
134 self.buffer.dep_encode_or_handle_err(dest, h)
135 }
136}
137
138impl<M: ManagedTypeApi> TopEncode for TokenIdentifier<M> {
139 #[inline]
140 fn top_encode_or_handle_err<O, H>(&self, output: O, h: H) -> Result<(), H::HandledErr>
141 where
142 O: TopEncodeOutput,
143 H: EncodeErrorHandler,
144 {
145 self.buffer.top_encode_or_handle_err(output, h)
146 }
147}
148
149impl<M: ManagedTypeApi> NestedDecode for TokenIdentifier<M> {
150 fn dep_decode_or_handle_err<I, H>(input: &mut I, h: H) -> Result<Self, H::HandledErr>
151 where
152 I: NestedDecodeInput,
153 H: DecodeErrorHandler,
154 {
155 Ok(TokenIdentifier::from(
156 ManagedBuffer::dep_decode_or_handle_err(input, h)?,
157 ))
158 }
159}
160
161impl<M: ManagedTypeApi> TopDecode for TokenIdentifier<M> {
162 fn top_decode_or_handle_err<I, H>(input: I, h: H) -> Result<Self, H::HandledErr>
163 where
164 I: TopDecodeInput,
165 H: DecodeErrorHandler,
166 {
167 Ok(TokenIdentifier::from(
168 ManagedBuffer::top_decode_or_handle_err(input, h)?,
169 ))
170 }
171}
172
173impl<M> TypeAbiFrom<&[u8]> for TokenIdentifier<M> where M: ManagedTypeApi {}
174impl<M> TypeAbiFrom<Vec<u8>> for TokenIdentifier<M> where M: ManagedTypeApi {}
175
176impl<M: ManagedTypeApi> TypeAbiFrom<Self> for TokenIdentifier<M> {}
177impl<M: ManagedTypeApi> TypeAbiFrom<&Self> for TokenIdentifier<M> {}
178
179impl<M: ManagedTypeApi> TypeAbi for TokenIdentifier<M> {
180 type Unmanaged = Self;
181
182 fn type_name() -> TypeName {
183 "TokenIdentifier".into()
184 }
185
186 fn type_name_rust() -> TypeName {
187 "TokenIdentifier<$API>".into()
188 }
189}
190
191impl<M: ManagedTypeApi> SCDisplay for TokenIdentifier<M> {
192 fn fmt<F: FormatByteReceiver>(&self, f: &mut F) {
193 f.append_managed_buffer(&ManagedBuffer::from_handle(
194 self.buffer.get_handle().cast_or_signal_error::<M, _>(),
195 ));
196 }
197}
198
199impl<M: ManagedTypeApi> SCLowerHex for TokenIdentifier<M> {
200 fn fmt<F: FormatByteReceiver>(&self, f: &mut F) {
201 f.append_managed_buffer_lower_hex(&ManagedBuffer::from_handle(
202 self.buffer.get_handle().cast_or_signal_error::<M, _>(),
203 ));
204 }
205}
206
207impl<M: ManagedTypeApi> core::fmt::Display for TokenIdentifier<M> {
208 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
209 let bytes = self.buffer.to_boxed_bytes();
210 let s = alloc::string::String::from_utf8_lossy(bytes.as_slice());
211 s.fmt(f)
212 }
213}
214
215impl<M: ManagedTypeApi> core::fmt::Debug for TokenIdentifier<M> {
216 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
217 f.debug_tuple("TokenIdentifier")
218 .field(&self.to_string())
219 .finish()
220 }
221}