Skip to main content

eosio_cdt/
print.rs

1use alloc::{string::String, vec::Vec};
2use eosio::{
3    AccountName, ActionName, Checksum160, Checksum256, Checksum512, Name,
4    PermissionName, PublicKey, ScopeName, Signature, TableName, TimePoint,
5    TimePointSec,
6};
7use eosio_cdt_sys::{
8    c_void, printdf, printhex, printi, printn, prints, prints_l, printsf,
9    printui,
10};
11
12/// Trait for types that can be printed from within EOSIO smart contracts
13pub trait Print {
14    /// Print to the console
15    fn print(&self);
16}
17
18impl Print for u8 {
19    #[inline]
20    fn print(&self) {
21        unsafe { printui(u64::from(*self)) }
22    }
23}
24
25impl Print for u16 {
26    #[inline]
27    fn print(&self) {
28        unsafe { printui(u64::from(*self)) }
29    }
30}
31
32impl Print for u32 {
33    #[inline]
34    fn print(&self) {
35        unsafe { printui(u64::from(*self)) }
36    }
37}
38
39impl Print for u64 {
40    #[inline]
41    fn print(&self) {
42        unsafe { printui(*self) }
43    }
44}
45
46impl Print for i8 {
47    #[inline]
48    fn print(&self) {
49        unsafe { printi(i64::from(*self)) }
50    }
51}
52
53impl Print for i16 {
54    #[inline]
55    fn print(&self) {
56        unsafe { printi(i64::from(*self)) }
57    }
58}
59
60impl Print for i32 {
61    #[inline]
62    fn print(&self) {
63        unsafe { printi(i64::from(*self)) }
64    }
65}
66
67impl Print for i64 {
68    #[inline]
69    fn print(&self) {
70        unsafe { printi(*self) }
71    }
72}
73
74impl<'a> Print for &'a str {
75    #[inline]
76    fn print(&self) {
77        let ptr = self.as_ptr();
78        #[allow(clippy::cast_possible_truncation)]
79        let len = self.len() as u32;
80        unsafe { prints_l(ptr, len) }
81    }
82}
83
84impl<'a> Print for String {
85    #[inline]
86    fn print(&self) {
87        self.as_str().print()
88    }
89}
90
91impl Print for bool {
92    #[inline]
93    fn print(&self) {
94        let out = if *self { "true" } else { "false" };
95        unsafe { prints(out.as_ptr()) }
96    }
97}
98
99impl Print for usize {
100    #[inline]
101    fn print(&self) {
102        (*self as u64).print()
103    }
104}
105
106impl Print for f32 {
107    #[inline]
108    fn print(&self) {
109        unsafe { printsf(*self) }
110    }
111}
112
113impl Print for f64 {
114    #[inline]
115    fn print(&self) {
116        unsafe { printdf(*self) }
117    }
118}
119
120impl Print for char {
121    #[inline]
122    fn print(&self) {
123        let num = *self as u8;
124        let ptr = &num as *const u8;
125        unsafe { prints_l(ptr, 1) }
126    }
127}
128
129impl<P> Print for Option<P>
130where
131    P: Print,
132{
133    #[inline]
134    fn print(&self) {
135        match self {
136            Some(p) => {
137                "Some(".print();
138                p.print();
139                ")".print();
140            }
141            None => "None".print(),
142        }
143    }
144}
145
146macro_rules! impl_print_for_names {
147    ($($ident:ident)*) => ($(
148        #[automatically_derived]
149        impl Print for $ident {
150            #[inline]
151            fn print(&self) {
152                unsafe { printn(self.as_u64()) }
153            }
154        }
155    )*)
156}
157
158impl_print_for_names! {
159    Name
160    AccountName
161    PermissionName
162    ScopeName
163    TableName
164    ActionName
165}
166
167impl Print for TimePoint {
168    #[inline]
169    fn print(&self) {
170        "TimePoint(".print();
171        self.as_micros().print();
172        ")".print();
173    }
174}
175
176impl Print for TimePointSec {
177    #[inline]
178    fn print(&self) {
179        "TimePointSec(".print();
180        self.as_secs().print();
181        ")".print();
182    }
183}
184
185/// Prints arbitrary data to the nodeos console
186#[macro_export]
187macro_rules! print {
188    ($e:expr) => (
189        $crate::Print::print(&$e);
190    );
191    ($e:expr, $($es:expr),+) => (
192        $crate::print!($e);
193        $crate::print!($($es),+);
194    );
195}
196
197impl Print for &[u8] {
198    #[inline]
199    #[allow(clippy::cast_possible_truncation)]
200    fn print(&self) {
201        let ptr = self.as_ptr() as *const c_void;
202        let len = self.len();
203        unsafe { printhex(ptr, len as u32) }
204    }
205}
206
207macro_rules! impl_print_for_as_slice_types {
208    ($($ident:ty)*) => ($(
209        #[automatically_derived]
210        impl Print for $ident {
211            #[inline]
212            fn print(&self) {
213                self.as_slice().print()
214            }
215        }
216    )*)
217}
218
219impl_print_for_as_slice_types! {
220    Vec<u8>
221    Checksum160
222    Checksum256
223    Checksum512
224    PublicKey
225    Signature
226}
227
228macro_rules! impl_print_for_byte_arrays {
229    ($($bytes:literal)*) => ($(
230        #[automatically_derived]
231        impl Print for [u8; $bytes] {
232            #[inline]
233            fn print(&self) {
234                (&self[..]).print()
235            }
236        }
237    )*)
238}
239
240impl_print_for_byte_arrays! {
241     1  2  3  4  5  6  7  8
242     9 10 11 12 13 14 15 16
243    17 18 19 20 21 22 23 24
244    25 26 27 28 29 30 31 32
245    33 34 35 36 37 38 39 40
246    41 42 43 44 45 46 47 48
247    49 50 51 52 53 54 55 56
248    57 58 59 60 61 62 63 64
249}