pub mod endian;
#[cfg(target_os = "linux")]
pub mod uds;
use std::sync::atomic::{AtomicU64, Ordering};
pub fn truncate_u64(val: u64, size: u64) -> u64 {
val & (u64::MAX >> (64 - (size << 3)))
}
#[macro_export]
macro_rules! align_up {
($num:expr, $bits:expr) => {{
let mask = (1 << $bits) - 1;
($num.wrapping_add(mask)) & !mask
}};
}
#[macro_export]
macro_rules! align_up_ty {
($num:expr, $ty:ty) => {{
let mask = ::core::mem::align_of::<$ty>() - 1;
($num.wrapping_add(mask)) & !mask
}};
}
#[macro_export]
macro_rules! align_down {
($num:expr, $bits:expr) => {{
let mask = (1 << $bits) - 1;
$num & !mask
}};
}
#[macro_export]
macro_rules! assign_bits {
($dst:expr, $src:expr, $mask:expr) => {
$dst = ($dst & !$mask) | ($src & $mask)
};
}
#[macro_export]
macro_rules! mask_bits {
($dst:expr, $src:expr, $mask:expr) => {
($dst & !$mask) | ($src & $mask)
};
}
#[cfg(target_arch = "x86_64")]
#[inline]
pub fn wrapping_sum<'a, T>(data: T) -> u8
where
T: IntoIterator<Item = &'a u8>,
{
data.into_iter().fold(0u8, |accu, e| accu.wrapping_add(*e))
}
pub fn get_atomic_low32(num: &AtomicU64) -> u32 {
num.load(Ordering::Acquire) as u32
}
pub fn get_atomic_high32(num: &AtomicU64) -> u32 {
(num.load(Ordering::Acquire) >> 32) as u32
}
pub fn set_low32(num: &mut u64, val: u32) {
*num &= !0xffff_ffff;
*num |= val as u64;
}
pub fn set_high32(num: &mut u64, val: u32) {
*num &= 0xffff_ffff;
*num |= (val as u64) << 32;
}
pub fn set_atomic_low32(num: &AtomicU64, val: u32) {
let mut cur = num.load(Ordering::Acquire);
set_low32(&mut cur, val);
num.store(cur, Ordering::Release)
}
pub fn set_atomic_high32(num: &AtomicU64, val: u32) {
let mut cur = num.load(Ordering::Acquire);
set_high32(&mut cur, val);
num.store(cur, Ordering::Release)
}
#[macro_export]
macro_rules! ffi {
($f:expr) => {{
let ret = $f;
if ret <= -1 {
Err(::std::io::Error::last_os_error())
} else {
Ok(ret)
}
}};
($f:expr, $failure:expr) => {{
let ret = $f;
if ret == $failure {
Err(::std::io::Error::last_os_error())
} else {
Ok(ret)
}
}};
}
#[macro_export]
macro_rules! consts {
(
$(#[$attr:meta])*
$vs:vis struct $EnumName:ident($TyName:ty) {
$( $(#[$vattr:meta])* $VARIANT:ident = $value:expr;)*
}
) => {
#[repr(transparent)]
#[derive(PartialEq, Eq, Copy, Clone)]
$(#[$attr])*
$vs struct $EnumName($TyName);
impl $EnumName {
$($(#[$vattr])* pub const $VARIANT: $EnumName = $EnumName($value);)*
#[allow(dead_code)]
pub const fn raw(self) -> $TyName {
self.0
}
#[allow(dead_code)]
pub const fn name(self) -> &'static str {
match self {
$($EnumName::$VARIANT => stringify!($VARIANT),)*
#[allow(unreachable_patterns)]
_ => "Unknown"
}
}
}
impl ::core::fmt::Debug for $EnumName {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_str(stringify!($EnumName))?;
match *self {
$($EnumName::$VARIANT => {
f.write_str("::")?;
f.write_str(stringify!($VARIANT))
})*
#[allow(unreachable_patterns)]
_ => {
::core::fmt::Write::write_char(f, '(')?;
::core::fmt::Debug::fmt(&self.0, f)?;
::core::fmt::Write::write_char(f, ')')
}
}
}
}
impl From<$EnumName> for $TyName {
fn from(value: $EnumName) -> Self {
value.0
}
}
impl From<$TyName> for $EnumName {
fn from(value: $TyName) -> Self {
$EnumName(value)
}
}
}
}
#[macro_export]
macro_rules! bitflags {
(
$(#[$attr:meta])*
$vs:vis struct $FlagTy:ident($TyName:ty) {
$(
$(#[$inner:ident $($args:tt)*])*
$FALG:ident = $value:expr;
)*
}
) => {
#[repr(transparent)]
#[derive(PartialEq, Eq, Copy, Clone, Hash)]
$(#[$attr])*
$vs struct $FlagTy($TyName);
::bitflags::bitflags! {
impl $FlagTy: $TyName {
$(
$(#[$inner $($args)*])*
const $FALG = $value;
)*
}
}
impl ::core::fmt::Debug for $FlagTy {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
if self.is_empty() {
write!(f, "0")
} else {
::bitflags::parser::to_writer(self, f)
}
}
}
};
}
#[cfg(test)]
#[path = "utils_test.rs"]
mod tests;