use std::mem;
use std::sync::OnceLock;
use bincode::config::{
AllowTrailing, FixintEncoding, LittleEndian, WithOtherEndian, WithOtherIntEncoding,
WithOtherTrailing,
};
use bincode::{DefaultOptions, Options};
use nix::sys::stat::mode_t;
use crate::FileType;
type BincodeConfigType = WithOtherIntEncoding<
WithOtherTrailing<WithOtherEndian<DefaultOptions, LittleEndian>, AllowTrailing>,
FixintEncoding,
>;
static BINCODE_CONFIG: OnceLock<BincodeConfigType> = OnceLock::new();
pub trait Apply: Sized {
fn apply<F>(mut self, f: F) -> Self
where
F: FnOnce(&mut Self),
{
f(&mut self);
self
}
}
impl<T> Apply for T {}
#[inline]
pub fn get_first_null_position(data: impl AsRef<[u8]>) -> Option<usize> {
data.as_ref().iter().position(|char| *char == 0)
}
#[cfg(target_os = "linux")]
#[allow(trivial_numeric_casts)]
pub const fn mode_from_kind_and_perm(kind: FileType, perm: u16) -> u32 {
kind.const_into_mode_t() | perm as mode_t
}
#[cfg(all(
not(target_os = "linux"),
any(target_os = "freebsd", target_os = "macos")
))]
#[allow(trivial_numeric_casts)]
pub const fn mode_from_kind_and_perm(kind: FileType, perm: u16) -> u32 {
(kind.const_into_mode_t() | perm as mode_t) as u32
}
#[allow(clippy::unnecessary_cast)] pub const fn perm_from_mode_and_kind(kind: FileType, mode: mode_t) -> u16 {
(mode ^ kind.const_into_mode_t()) as u16
}
#[inline]
pub const fn get_padding_size(dir_entry_size: usize) -> usize {
let entry_size = (dir_entry_size + mem::size_of::<u64>() - 1) & !(mem::size_of::<u64>() - 1);
entry_size - dir_entry_size
}
#[inline]
pub fn get_bincode_config() -> &'static BincodeConfigType {
BINCODE_CONFIG.get_or_init(|| {
DefaultOptions::new()
.with_little_endian()
.allow_trailing_bytes()
.with_fixint_encoding()
})
}