use crate::fs::{access_impl, FollowSymlinks};
#[cfg(racy_asserts)]
use crate::fs::{access_unchecked, file_path};
use std::path::Path;
use std::{fs, io};
#[derive(Clone, Copy, Debug)]
pub struct AccessModes {
pub readable: bool,
pub writable: bool,
pub executable: bool,
}
#[derive(Clone, Copy, Debug)]
pub enum AccessType {
Access(AccessModes),
Exists,
}
#[cfg_attr(not(racy_asserts), allow(clippy::let_and_return))]
pub fn access(
start: &fs::File,
path: &Path,
type_: AccessType,
follow: FollowSymlinks,
) -> io::Result<()> {
let result = access_impl(start, path, type_, follow);
#[cfg(racy_asserts)]
let unchecked = access_unchecked(start, path, type_, follow);
#[cfg(racy_asserts)]
check_access(start, path, type_, follow, &result, &unchecked);
result
}
#[cfg(racy_asserts)]
#[allow(clippy::enum_glob_use)]
fn check_access(
start: &fs::File,
path: &Path,
_type_: AccessType,
_follow: FollowSymlinks,
result: &io::Result<()>,
unchecked: &io::Result<()>,
) {
use io::ErrorKind::*;
match (map_result(result), map_result(stat)) {
(Ok(()), Ok(())) => {}
(Err((PermissionDenied, message)), _) => {
}
(Err((kind, message)), Err((unchecked_kind, unchecked_message))) => {
assert_eq!(kind, unchecked_kind);
assert_eq!(
message,
unchecked_message,
"start='{:?}', path='{:?}'",
start,
path.display()
);
}
other => panic!(
"unexpected result from access start='{:?}', path='{}':\n{:#?}",
start,
path.display(),
other,
),
}
}