#[cfg(feature = "alloc")]
pub use alloc::borrow;
#[doc(hidden)]
pub use futures_util::{join, try_join};
pub mod boxed {
#[cfg(feature = "alloc")]
pub use alloc::boxed::Box;
}
pub mod collections {
#[cfg(feature = "alloc")]
pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
pub use hashbrown::{HashMap, HashSet};
pub mod hash_map {
pub use hashbrown::hash_map::{Entry, EntryRef};
pub use hashbrown::Equivalent;
}
#[cfg(feature = "alloc")]
pub mod btree_map {
pub use alloc::collections::btree_map::Entry;
}
}
pub mod error {
#[cfg(not(feature = "std"))]
pub trait Error: core::fmt::Debug + core::fmt::Display {
fn source(&self) -> Option<&(dyn Error + 'static)> {
None
}
}
#[cfg(feature = "std")]
pub use std::error::Error;
}
#[cfg(feature = "alloc")]
pub use alloc::format;
#[cfg(not(feature = "std"))]
pub use core2::io;
#[cfg(feature = "std")]
pub use std::io;
#[cfg(feature = "std")]
pub use std::net;
#[cfg(all(not(feature = "std"), feature = "alloc"))]
pub mod println {
#[macro_export]
macro_rules! println {
($($arg:tt)*) => {{
tracing::info!($($arg)*);
}};
}
}
pub mod rand {
pub use rand::distributions;
pub use rand::prelude;
pub use rand::CryptoRng;
pub use rand::Error;
pub use rand::Rng;
pub use rand::RngCore;
#[cfg(not(feature = "std"))]
pub use not_random::thread_rng;
#[cfg(feature = "std")]
pub use rand::thread_rng;
#[cfg(not(feature = "std"))]
pub use not_random::random;
#[cfg(feature = "std")]
pub use rand::random;
#[cfg(feature = "std")]
pub use rand::rngs;
#[cfg(not(feature = "std"))]
pub mod rngs {
pub use super::not_random::OsRng;
}
#[cfg(feature = "std")]
pub fn random_string() -> String {
use rand::distributions::{Alphanumeric, DistString};
Alphanumeric.sample_string(&mut thread_rng(), 16)
}
#[cfg(not(feature = "std"))]
mod not_random {
use super::*;
#[derive(Clone)]
pub struct FakeRng(rand_pcg::Lcg64Xsh32);
impl CryptoRng for FakeRng {}
impl RngCore for FakeRng {
fn next_u32(&mut self) -> u32 {
self.0.gen()
}
fn next_u64(&mut self) -> u64 {
self.0.gen()
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
if let Err(e) = self.0.try_fill_bytes(dest) {
panic!("Error: {}", e);
}
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
self.0.try_fill(dest)
}
}
#[allow(unsafe_code, static_mut_refs)]
pub fn thread_rng() -> FakeRng {
use rand::SeedableRng;
static mut RNG: Option<rand_pcg::Lcg64Xsh32> = None;
unsafe {
if RNG.is_none() {
RNG = Some(rand_pcg::Pcg32::seed_from_u64(1234));
}
}
let lcg = unsafe { rand_pcg::Pcg32::seed_from_u64(RNG.as_mut().unwrap().gen()) };
FakeRng(lcg)
}
pub fn random<T>() -> T
where
distributions::Standard: prelude::Distribution<T>,
{
let mut rng = thread_rng();
rng.gen()
}
pub struct OsRng;
impl CryptoRng for OsRng {}
impl RngCore for OsRng {
fn next_u32(&mut self) -> u32 {
let mut rng = thread_rng();
rng.gen()
}
fn next_u64(&mut self) -> u64 {
let mut rng = thread_rng();
rng.gen()
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
if let Err(e) = self.try_fill_bytes(dest) {
panic!("Error: {}", e);
}
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
let mut rng = thread_rng();
rng.try_fill(dest)
}
}
}
}
pub mod string {
#[cfg(feature = "alloc")]
pub use alloc::string::{String, ToString};
#[cfg(not(feature = "alloc"))]
use heapless::String as ByteString;
}
pub mod str {
#[cfg(feature = "alloc")]
pub use alloc::str::from_utf8;
#[cfg(feature = "alloc")]
pub use alloc::str::FromStr;
}
#[cfg(not(feature = "std"))]
pub mod sync {
use core::convert::Infallible;
pub use alloc::sync::{Arc, Weak};
#[derive(Debug)]
pub struct RwLock<T>(spin::RwLock<T>);
pub type RwLockWriteGuard<'a, T> = spin::RwLockWriteGuard<'a, T>;
impl<T> RwLock<T> {
pub fn new(value: T) -> Self {
RwLock(spin::RwLock::new(value))
}
pub fn read(&self) -> Result<spin::RwLockReadGuard<'_, T>, Infallible> {
Ok(self.0.read())
}
pub fn write(&self) -> Result<spin::RwLockWriteGuard<'_, T>, Infallible> {
Ok(self.0.write())
}
}
impl<T: Default> Default for RwLock<T> {
fn default() -> Self {
Self::new(Default::default())
}
}
impl<T> From<T> for RwLock<T> {
fn from(t: T) -> Self {
Self::new(t)
}
}
impl<T> core::ops::Deref for RwLock<T> {
type Target = spin::RwLock<T>;
fn deref(&self) -> &spin::RwLock<T> {
&self.0
}
}
impl<T> core::ops::DerefMut for RwLock<T> {
fn deref_mut(&mut self) -> &mut spin::RwLock<T> {
&mut self.0
}
}
pub struct Mutex<T>(spin::Mutex<T>);
impl<T> Mutex<T> {
pub const fn new(value: T) -> Self {
Mutex(spin::Mutex::new(value))
}
pub fn lock(&self) -> Result<spin::MutexGuard<'_, T>, Infallible> {
Ok(self.0.lock())
}
}
impl<T> core::ops::Deref for Mutex<T> {
type Target = spin::Mutex<T>;
fn deref(&self) -> &spin::Mutex<T> {
&self.0
}
}
impl<T> core::ops::DerefMut for Mutex<T> {
fn deref_mut(&mut self) -> &mut spin::Mutex<T> {
&mut self.0
}
}
impl<T> Default for Mutex<T>
where
T: Default,
{
fn default() -> Self {
Self::new(Default::default())
}
}
impl<T> From<T> for Mutex<T> {
fn from(t: T) -> Self {
Self::new(t)
}
}
}
#[cfg(feature = "std")]
pub mod sync {
pub use std::sync::{Arc, Weak};
pub use std::sync::{Mutex, RwLock};
}
#[cfg(not(feature = "std"))]
pub mod task {
#[cfg(feature = "alloc")]
pub use alloc::task::*;
pub use core::task::*;
}
#[cfg(feature = "std")]
pub use std::task;
pub mod vec {
#[cfg(feature = "alloc")]
pub use alloc::vec;
#[cfg(feature = "alloc")]
pub use alloc::vec::*;
#[cfg(not(feature = "alloc"))]
pub type Vec<T> = heapless::Vec<T, 64>;
}
#[cfg(feature = "std")]
pub mod time {
pub use std::time::*;
pub fn now() -> crate::Result<u64> {
if let Ok(now) = SystemTime::now().duration_since(UNIX_EPOCH) {
Ok(now.as_secs())
} else {
Err(crate::Error::new(
crate::errcode::Origin::Core,
crate::errcode::Kind::Unsupported,
"Can't get time",
))?
}
}
}
#[cfg(not(feature = "std"))]
pub mod time {
pub use core::time::Duration;
#[cfg(not(feature = "std"))]
pub fn now() -> crate::Result<u64> {
match utcnow::utcnow() {
Ok(time) => Ok(time.as_secs() as u64),
Err(_err) => Err(crate::Error::new(
crate::errcode::Origin::Core,
crate::errcode::Kind::Unsupported,
"Can't get time",
))?,
}
}
}
pub mod fmt {
#[cfg(feature = "alloc")]
pub use alloc::fmt::*;
#[cfg(not(feature = "alloc"))]
pub use core::fmt::*;
}
pub mod future {
use crate::{
errcode::{Kind, Origin},
Error, Result,
};
use futures_util::future::{Future, FutureExt};
pub fn poll_once<'a, F, T>(future: F) -> Result<T>
where
F: Future<Output = Result<T>> + Send + 'a,
{
use core::task::{Context, Poll};
use core::task::{RawWaker, RawWakerVTable, Waker};
fn dummy_raw_waker() -> RawWaker {
fn no_op(_: *const ()) {}
fn clone(_: *const ()) -> RawWaker {
dummy_raw_waker()
}
let vtable = &RawWakerVTable::new(clone, no_op, no_op, no_op);
RawWaker::new(core::ptr::null(), vtable)
}
fn dummy_waker() -> Waker {
#[allow(unsafe_code)]
unsafe {
Waker::from_raw(dummy_raw_waker())
}
}
let waker = dummy_waker();
let mut context = Context::from_waker(&waker);
let result = future.boxed().poll_unpin(&mut context);
assert!(
result.is_ready(),
"poll_once() only accepts futures that resolve after being polled once"
);
match result {
Poll::Ready(value) => value,
Poll::Pending => Err(Error::new_without_cause(Origin::Core, Kind::Invalid)),
}
}
}