1#[cfg(feature = "alloc")]
15pub use alloc::borrow;
16
17#[doc(hidden)]
18pub use futures_util::{join, try_join};
19
20pub mod boxed {
22 #[cfg(feature = "alloc")]
23 pub use alloc::boxed::Box;
24}
25
26pub mod collections {
29 #[cfg(feature = "alloc")]
30 pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
31
32 pub use hashbrown::{HashMap, HashSet};
33
34 pub mod hash_map {
36 pub use hashbrown::hash_map::{Entry, EntryRef};
37 pub use hashbrown::Equivalent;
38 }
39
40 #[cfg(feature = "alloc")]
42 pub mod btree_map {
43 pub use alloc::collections::btree_map::Entry;
44 }
45}
46
47pub mod error {
49 #[cfg(not(feature = "std"))]
50 pub trait Error: core::fmt::Debug + core::fmt::Display {
52 fn source(&self) -> Option<&(dyn Error + 'static)> {
54 None
55 }
56 }
57 #[cfg(feature = "std")]
58 pub use std::error::Error;
59}
60
61#[cfg(feature = "alloc")]
63pub use alloc::format;
64
65#[cfg(not(feature = "std"))]
67pub use core2::io;
68#[cfg(feature = "std")]
69pub use std::io;
70
71#[cfg(feature = "std")]
73pub use std::net;
74
75#[cfg(all(not(feature = "std"), feature = "alloc"))]
77pub mod println {
78 #[macro_export]
79 macro_rules! println {
81 ($($arg:tt)*) => {{
82 tracing::info!($($arg)*);
83 }};
84 }
85}
86
87pub mod rand {
89 pub use rand::distributions;
90 pub use rand::prelude;
91 pub use rand::CryptoRng;
92 pub use rand::Error;
93 pub use rand::Rng;
94 pub use rand::RngCore;
95
96 #[cfg(not(feature = "std"))]
97 pub use not_random::thread_rng;
98 #[cfg(feature = "std")]
99 pub use rand::thread_rng;
100
101 #[cfg(not(feature = "std"))]
102 pub use not_random::random;
103 #[cfg(feature = "std")]
104 pub use rand::random;
105
106 #[cfg(feature = "std")]
108 pub use rand::rngs;
109 #[cfg(not(feature = "std"))]
110 pub mod rngs {
115 pub use super::not_random::OsRng;
116 }
117
118 #[cfg(feature = "std")]
120 pub fn random_string() -> String {
121 use rand::distributions::{Alphanumeric, DistString};
122 Alphanumeric.sample_string(&mut thread_rng(), 16)
123 }
124
125 #[cfg(not(feature = "std"))]
131 mod not_random {
132 use super::*;
133
134 #[derive(Clone)]
135 pub struct FakeRng(rand_pcg::Lcg64Xsh32);
136
137 impl CryptoRng for FakeRng {}
138
139 impl RngCore for FakeRng {
140 fn next_u32(&mut self) -> u32 {
141 self.0.gen()
142 }
143
144 fn next_u64(&mut self) -> u64 {
145 self.0.gen()
146 }
147
148 fn fill_bytes(&mut self, dest: &mut [u8]) {
149 if let Err(e) = self.0.try_fill_bytes(dest) {
150 panic!("Error: {}", e);
151 }
152 }
153
154 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
155 self.0.try_fill(dest)
156 }
157 }
158
159 #[allow(unsafe_code, static_mut_refs)]
165 pub fn thread_rng() -> FakeRng {
166 use rand::SeedableRng;
167 static mut RNG: Option<rand_pcg::Lcg64Xsh32> = None;
168 unsafe {
169 if RNG.is_none() {
170 RNG = Some(rand_pcg::Pcg32::seed_from_u64(1234));
171 }
172 }
173 let lcg = unsafe { rand_pcg::Pcg32::seed_from_u64(RNG.as_mut().unwrap().gen()) };
174
175 FakeRng(lcg)
176 }
177
178 pub fn random<T>() -> T
181 where
182 distributions::Standard: prelude::Distribution<T>,
183 {
184 let mut rng = thread_rng();
185 rng.gen()
186 }
187
188 pub struct OsRng;
190
191 impl CryptoRng for OsRng {}
192
193 impl RngCore for OsRng {
194 fn next_u32(&mut self) -> u32 {
195 let mut rng = thread_rng();
196 rng.gen()
197 }
198
199 fn next_u64(&mut self) -> u64 {
200 let mut rng = thread_rng();
201 rng.gen()
202 }
203
204 fn fill_bytes(&mut self, dest: &mut [u8]) {
205 if let Err(e) = self.try_fill_bytes(dest) {
206 panic!("Error: {}", e);
207 }
208 }
209
210 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
211 let mut rng = thread_rng();
212 rng.try_fill(dest)
213 }
214 }
215 }
216}
217
218pub mod string {
220 #[cfg(feature = "alloc")]
221 pub use alloc::string::{String, ToString};
222 #[cfg(not(feature = "alloc"))]
223 use heapless::String as ByteString;
224}
225
226pub mod str {
228 #[cfg(feature = "alloc")]
229 pub use alloc::str::from_utf8;
230 #[cfg(feature = "alloc")]
231 pub use alloc::str::FromStr;
232}
233
234#[cfg(not(feature = "std"))]
236pub mod sync {
237 use core::convert::Infallible;
238
239 pub use alloc::sync::{Arc, Weak};
240
241 #[derive(Debug)]
243 pub struct RwLock<T>(spin::RwLock<T>);
244
245 pub type RwLockWriteGuard<'a, T> = spin::RwLockWriteGuard<'a, T>;
247
248 impl<T> RwLock<T> {
249 pub fn new(value: T) -> Self {
251 RwLock(spin::RwLock::new(value))
252 }
253 pub fn read(&self) -> Result<spin::RwLockReadGuard<'_, T>, Infallible> {
256 Ok(self.0.read())
257 }
258 pub fn write(&self) -> Result<spin::RwLockWriteGuard<'_, T>, Infallible> {
261 Ok(self.0.write())
262 }
263 }
264 impl<T: Default> Default for RwLock<T> {
265 fn default() -> Self {
266 Self::new(Default::default())
267 }
268 }
269 impl<T> From<T> for RwLock<T> {
270 fn from(t: T) -> Self {
271 Self::new(t)
272 }
273 }
274 impl<T> core::ops::Deref for RwLock<T> {
275 type Target = spin::RwLock<T>;
276 fn deref(&self) -> &spin::RwLock<T> {
277 &self.0
278 }
279 }
280 impl<T> core::ops::DerefMut for RwLock<T> {
281 fn deref_mut(&mut self) -> &mut spin::RwLock<T> {
282 &mut self.0
283 }
284 }
285
286 pub struct Mutex<T>(spin::Mutex<T>);
288 impl<T> Mutex<T> {
289 pub const fn new(value: T) -> Self {
291 Mutex(spin::Mutex::new(value))
292 }
293 pub fn lock(&self) -> Result<spin::MutexGuard<'_, T>, Infallible> {
295 Ok(self.0.lock())
296 }
297 }
298 impl<T> core::ops::Deref for Mutex<T> {
299 type Target = spin::Mutex<T>;
300 fn deref(&self) -> &spin::Mutex<T> {
301 &self.0
302 }
303 }
304 impl<T> core::ops::DerefMut for Mutex<T> {
305 fn deref_mut(&mut self) -> &mut spin::Mutex<T> {
306 &mut self.0
307 }
308 }
309 impl<T> Default for Mutex<T>
310 where
311 T: Default,
312 {
313 fn default() -> Self {
314 Self::new(Default::default())
315 }
316 }
317 impl<T> From<T> for Mutex<T> {
318 fn from(t: T) -> Self {
319 Self::new(t)
320 }
321 }
322}
323#[cfg(feature = "std")]
325pub mod sync {
326 pub use std::sync::{Arc, Weak};
327 pub use std::sync::{Mutex, RwLock};
328}
329
330#[cfg(not(feature = "std"))]
332pub mod task {
333 #[cfg(feature = "alloc")]
336 pub use alloc::task::*;
337 pub use core::task::*;
338}
339
340#[cfg(feature = "std")]
342pub use std::task;
343
344pub mod vec {
346 #[cfg(feature = "alloc")]
347 pub use alloc::vec;
348 #[cfg(feature = "alloc")]
349 pub use alloc::vec::*;
350 #[cfg(not(feature = "alloc"))]
351 pub type Vec<T> = heapless::Vec<T, 64>;
352}
353
354#[cfg(feature = "std")]
356pub mod time {
357 pub use std::time::*;
358
359 pub fn now() -> crate::Result<u64> {
361 if let Ok(now) = SystemTime::now().duration_since(UNIX_EPOCH) {
362 Ok(now.as_secs())
363 } else {
364 Err(crate::Error::new(
365 crate::errcode::Origin::Core,
366 crate::errcode::Kind::Unsupported,
367 "Can't get time",
368 ))?
369 }
370 }
371}
372
373#[cfg(not(feature = "std"))]
375pub mod time {
376 pub use core::time::Duration;
377
378 #[cfg(not(feature = "std"))]
380 pub fn now() -> crate::Result<u64> {
381 match utcnow::utcnow() {
382 Ok(time) => Ok(time.as_secs() as u64),
383 Err(_err) => Err(crate::Error::new(
384 crate::errcode::Origin::Core,
385 crate::errcode::Kind::Unsupported,
386 "Can't get time",
387 ))?,
388 }
389 }
390}
391
392pub mod fmt {
394 #[cfg(feature = "alloc")]
395 pub use alloc::fmt::*;
396 #[cfg(not(feature = "alloc"))]
397 pub use core::fmt::*;
398}
399
400pub mod future {
402 use crate::{
403 errcode::{Kind, Origin},
404 Error, Result,
405 };
406 use futures_util::future::{Future, FutureExt};
407
408 pub fn poll_once<'a, F, T>(future: F) -> Result<T>
413 where
414 F: Future<Output = Result<T>> + Send + 'a,
415 {
416 use core::task::{Context, Poll};
417 use core::task::{RawWaker, RawWakerVTable, Waker};
418
419 fn dummy_raw_waker() -> RawWaker {
420 fn no_op(_: *const ()) {}
421 fn clone(_: *const ()) -> RawWaker {
422 dummy_raw_waker()
423 }
424 let vtable = &RawWakerVTable::new(clone, no_op, no_op, no_op);
425 RawWaker::new(core::ptr::null(), vtable)
426 }
427
428 fn dummy_waker() -> Waker {
429 #[allow(unsafe_code)]
432 unsafe {
433 Waker::from_raw(dummy_raw_waker())
434 }
435 }
436
437 let waker = dummy_waker();
438 let mut context = Context::from_waker(&waker);
439 let result = future.boxed().poll_unpin(&mut context);
440 assert!(
441 result.is_ready(),
442 "poll_once() only accepts futures that resolve after being polled once"
443 );
444 match result {
445 Poll::Ready(value) => value,
446 Poll::Pending => Err(Error::new_without_cause(Origin::Core, Kind::Invalid)),
447 }
448 }
449}