// File mode utilities for ZIP archives
///|
/// Unix file mode (permission bits)
pub(all) struct FileMode(Int) derive(Eq, Compare, ToJson, FromJson, Hash)
///|
pub extend FileMode with Eq::{not_equal, equal}
///|
pub extend FileMode with Compare::{op_lt, op_le, op_ge, compare, op_gt}
///|
pub extend FileMode with ToJson::{to_json}
///|
pub extend FileMode with @json.FromJson::{from_json}
///|
pub extend FileMode with Hash::{hash, hash_combine}
///|
/// Get the integer value of the file mode
/// Raw integer permission bits (includes type bits if supplied externally).
pub fn FileMode::to_int(self : FileMode) -> Int {
self.0
}
///|
/// Create FileMode from integer
/// Wrap raw bits in FileMode.
pub fn FileMode::from_int(value : Int) -> FileMode {
FileMode(value)
}
///|
/// String representation for display
pub impl Show for FileMode with fn output(x, logger) {
Show::output(x.0, logger)
}
///|
/// Convert to string (returns the integer as string)
pub impl Show for FileMode with fn to_string(x) {
x.0.to_string()
}
///|
pub extend FileMode with Show::{to_string, output}
///|
/// Format Unix file mode like ls -l (e.g., "rwxr-xr-x")
/// Render rwx triads (owner/group/other).
pub fn format_file_mode(mode : FileMode) -> String {
fn format_entity(m : Int) -> String {
let r = if (m & 0o4) != 0 { "r" } else { "-" }
let w = if (m & 0o2) != 0 { "w" } else { "-" }
let x = if (m & 0o1) != 0 { "x" } else { "-" }
r + w + x
}
let mode_int = mode.0
format_entity(mode_int >> 6) +
format_entity(mode_int >> 3) +
format_entity(mode_int)
}