1use crate::{Error, Result, Time};
2use std::{io, mem::size_of_val, str, time};
3
4#[inline(always)]
5pub fn time_from_nanos(nanos: u64) -> Time {
6 time::Duration::from_nanos(nanos)
7}
8
9#[inline(always)]
10pub fn is_set<T>(flags: T, flag: T) -> bool
11where
12 T: core::ops::BitAnd<Output = T> + Eq + Copy,
13{
14 flags & flag == flag
15}
16
17#[inline(always)]
18pub fn invalid_input(msg: &'static str) -> Error {
19 Error::new(io::ErrorKind::InvalidInput, msg)
20}
21
22#[inline(always)]
23pub fn invalid_data(msg: &'static str) -> Error {
24 Error::new(io::ErrorKind::InvalidData, msg)
25}
26
27#[inline(always)]
28pub fn check_size<T: ?Sized>(len: usize, val: &T) -> Result<()> {
29 if len == size_of_val(val) {
30 Ok(())
31 } else {
32 Err(invalid_data("Unexpected size"))
33 }
34}
35
36#[inline(always)]
37pub fn check_len<V, T: ?Sized>(slice: &[V], val: &T) -> Result<()> {
38 if slice.len() <= size_of_val(val) {
39 Ok(())
40 } else {
41 Err(invalid_input("Too many values"))
42 }
43}
44
45#[inline(always)]
46pub fn check_len_str<T: ?Sized>(slice: &str, val: &T) -> Result<()> {
47 if slice.as_bytes().len() < size_of_val(val) {
48 Ok(())
49 } else {
50 Err(invalid_input("String too long"))
51 }
52}
53
54#[inline(always)]
55pub fn safe_set_str<const N: usize>(dst: &mut [u8; N], src: &str) -> Result<()> {
56 check_len_str(src, dst)?;
57
58 let src = src.as_bytes();
59 dst[..src.len()].copy_from_slice(src);
60 dst[src.len()] = 0;
61
62 Ok(())
63}
64
65#[inline(always)]
66pub fn safe_get_str(src: &[u8]) -> Result<&str> {
67 Ok(str::from_utf8(src)
68 .map_err(|_| invalid_data("Invalid UTF-8"))?
69 .trim_end_matches('\0'))
70}
71
72#[inline(always)]
74pub fn major(dev: u64) -> u64 {
75 let mut major = 0;
76 major |= (dev & 0x00000000000fff00) >> 8;
77 major |= (dev & 0xfffff00000000000) >> 32;
78 major
79}
80
81#[inline(always)]
83pub fn minor(dev: u64) -> u64 {
84 let mut minor = 0;
85 minor |= dev & 0x00000000000000ff;
86 minor |= (dev & 0x00000ffffff00000) >> 12;
87 minor
88}
89
90pub fn set_nonblock(fd: std::os::unix::io::RawFd) -> Result<()> {
92 use nix::fcntl::{fcntl, FcntlArg, OFlag};
93
94 let mut flags = OFlag::from_bits_truncate(fcntl(fd, FcntlArg::F_GETFL)?);
95
96 flags.insert(OFlag::O_NONBLOCK);
97
98 fcntl(fd, FcntlArg::F_SETFL(flags))?;
99
100 Ok(())
101}