numext_constructor/fixed_hash/core/internal/
public_basic.rs

1// Copyright 2018-2019 Cryptape Technologies LLC.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Define public methods about bits and bytes.
10
11use crate::fixed_hash::HashConstructor;
12use crate::utils;
13use quote::quote;
14
15impl HashConstructor {
16    pub fn defun_pub_basic(&self) {
17        self.defun_pub_bits_ops();
18        self.defun_pub_bytes_ops();
19        self.defun_pub_ptr_ops();
20        self.defun_pub_mem_ops();
21    }
22
23    fn defun_pub_bits_ops(&self) {
24        let bits_size = &self.ts.bits_size;
25        let loop_unit_amount = &utils::pure_uint_list_to_ts(0..self.info.unit_amount);
26        let loop_unit_amount_rev = &utils::pure_uint_list_to_ts((0..self.info.unit_amount).rev());
27        let part = quote!(
28            /// Return the count of bits.
29            #[inline]
30            pub const fn count_bits() -> u64 {
31                #bits_size
32            }
33            /// Return a specific bit, or return None when overlows.
34            ///
35            /// Order from low to high.
36            #[inline]
37            pub fn bit(&self, index: usize) -> Option<bool> {
38                if index >= #bits_size {
39                    None
40                } else {
41                    let inner = self.inner();
42                    let unit_idx = index / 8;
43                    let bit_idx = index % 8;
44                    Some(inner[unit_idx] & (1 << bit_idx) != 0)
45                }
46            }
47            /// Set a specific bit.
48            /// Return false when overflows.
49            ///
50            /// Order from low to high.
51            #[inline]
52            pub fn set_bit(&mut self, index: usize, value: bool) -> bool {
53                if index >= #bits_size {
54                    false
55                } else {
56                    let inner = self.mut_inner();
57                    let unit_idx = index / 8;
58                    let bit_idx = index % 8;
59                    if value {
60                        inner[unit_idx] |= 1 << bit_idx;
61                    } else {
62                        inner[unit_idx] &= !(1 << bit_idx);
63                    }
64                    true
65                }
66            }
67            /// Return the highest bit which is one.
68            ///
69            /// Order from low to high.
70            #[inline]
71            pub fn highest_one(&self) -> Option<usize> {
72                let inner = self.inner();
73                #({
74                    let idx = #loop_unit_amount_rev;
75                    let v = inner[idx];
76                    if v != 0 {
77                        let x = 8 * (idx + 1) - 1;
78                        let y = v.leading_zeros() as usize;
79                        return Some(x - y);
80                    }
81                })*
82                None
83            }
84            /// Return the lowest bit which is one.
85            ///
86            /// Order from low to high.
87            #[inline]
88            pub fn lowest_one(&self) -> Option<usize> {
89                let inner = self.inner();
90                #({
91                    let idx = #loop_unit_amount;
92                    let v = inner[idx];
93                    if v != 0 {
94                        let x = 8 * idx;
95                        let y = v.trailing_zeros() as usize;
96                        return Some(x + y);
97                    }
98                })*
99                None
100            }
101        );
102        self.defun(part);
103    }
104
105    fn defun_pub_bytes_ops(&self) {
106        let bytes_size = &self.ts.unit_amount;
107        let loop_unit_amount = &utils::pure_uint_list_to_ts(0..self.info.unit_amount);
108        let loop_unit_amount_rev = &utils::pure_uint_list_to_ts((0..self.info.unit_amount).rev());
109        let part = quote!(
110            /// Return the count of bytes.
111            #[inline]
112            pub const fn count_bytes() -> u64 {
113                #bytes_size
114            }
115            /// Return a specific byte, or return None when overlows.
116            #[inline]
117            pub fn byte(&self, index: usize) -> Option<u8> {
118                if index >= #bytes_size {
119                    None
120                } else {
121                    let inner = self.inner();
122                    Some(inner[index])
123                }
124            }
125            /// Set a specific byte.
126            /// Return false when overflows;
127            #[inline]
128            pub fn set_byte(&mut self, index: usize, byte: u8) -> bool {
129                if index >= #bytes_size {
130                    false
131                } else {
132                    let inner = self.mut_inner();
133                    inner[index] = byte;
134                    true
135                }
136            }
137            /// Return the highest byte which is nonzero.
138            #[inline]
139            pub fn highest_nonzero_byte(&self) -> Option<usize> {
140                let inner = self.inner();
141                #({
142                    let idx: usize = #loop_unit_amount_rev;
143                    let v = inner[idx];
144                    if v != 0 {
145                        return Some(idx);
146                    }
147                })*
148                None
149            }
150            /// Return the lowest byte which is nonzero.
151            #[inline]
152            pub fn lowest_nonzero_byte(&self) -> Option<usize> {
153                let inner = self.inner();
154                #({
155                    let idx: usize = #loop_unit_amount;
156                    let v = inner[idx];
157                    if v != 0 {
158                        return Some(idx);
159                    }
160                })*
161                None
162            }
163        );
164        self.defun(part);
165    }
166
167    fn defun_pub_ptr_ops(&self) {
168        let inner_type = &self.ts.inner_type;
169        let part = quote!(
170            /// Get the inner bytes slice of a fixed hash.
171            #[inline]
172            pub fn as_bytes(&self) -> &[u8] {
173                &self.inner()[..]
174            }
175            /// Get the mutable inner bytes slice of a fixed hash.
176            #[inline]
177            pub fn as_bytes_mut(&mut self) -> &mut [u8] {
178                &mut self.mut_inner()[..]
179            }
180            /// Get the inner bytes of a fixed hash.
181            #[inline]
182            pub fn as_fixed_bytes(&self) -> &#inner_type {
183                self.inner()
184            }
185            /// Get the mutable inner bytes of a fixed hash.
186            #[inline]
187            pub fn as_fixed_bytes_mut(&mut self) -> &mut #inner_type {
188                self.mut_inner()
189            }
190            /// Get the inner bytes array of a fixed hash.
191            #[inline]
192            pub fn into_fixed_bytes(self) -> #inner_type {
193                self.into_inner()
194            }
195            /// Get a vec of a fixed hash.
196            #[inline]
197            pub fn to_vec(&self) -> Vec<u8> {
198                self.inner().to_vec()
199            }
200            /// Get a constant raw pointer to the inner bytes array of a fixed hash.
201            #[inline]
202            pub fn as_ptr(&self) -> *const u8 {
203                self.inner().as_ptr()
204            }
205            /// Get a mutable raw pointer to the inner bytes array of a fixed hash.
206            #[inline]
207            pub fn as_mut_ptr(&mut self) -> *mut u8 {
208                self.mut_inner().as_mut_ptr()
209            }
210        );
211        self.defun(part);
212    }
213
214    fn defun_pub_mem_ops(&self) {
215        let bytes_size = &self.ts.unit_amount;
216        let part = quote!(
217            /// Return the size used by this type in bytes, actually.
218            ///
219            /// This size is greater than or equal to the bytes of this fixed type.
220            #[inline]
221            pub const fn size_of() -> usize {
222                #bytes_size
223            }
224        );
225        self.defun(part);
226    }
227}