filemode
A Rust library for converting between Unix mode_t and Go os.FileMode formats.
Overview
This crate provides type-safe, zero-cost abstractions for converting file permission and type information between Unix (POSIX) systems and Go's file mode representation. It's particularly useful when working with systems that bridge Rust and Go ecosystems, such as BuildKit, Docker, or other container build systems.
Features
- Type-safe conversions - Prevents accidental mixing of Unix and Go mode values
- Zero-cost abstractions - All conversions are inlined with no runtime overhead
- Idiomatic Rust - Uses
From/Intotraits for ergonomic conversions - Well-tested - Comprehensive test coverage including edge cases
- Well-documented - Detailed documentation with examples
- Backward compatible - Maintains legacy function API
Installation
Add this to your Cargo.toml:
[]
= "0.1"
Usage
Type-Safe API (Recommended)
use ;
// Convert Unix directory mode to Go FileMode
let unix_mode = from;
let go_mode: GoFileMode = unix_mode.into;
assert_eq!; // ModeDir | 0o755
// Convert Unix regular file mode
let unix_mode = from;
let go_mode = from;
assert_eq!;
Legacy Function API
use unix_mode_to_go_filemode;
// Directory with 0o755 permissions
let go_mode = unix_mode_to_go_filemode;
assert_eq!;
// Regular file with 0o644 permissions
let go_mode = unix_mode_to_go_filemode;
assert_eq!;
Real-World Example
use fs;
use PermissionsExt;
use ;
// Get file metadata from filesystem
let metadata = metadata?;
let unix_mode = metadata.permissions.mode;
// Convert to Go FileMode for use with BuildKit or other Go-based tools
let go_mode = from;
// Send go_mode.as_u32() to your gRPC/protocol buffer message
Technical Details
Unix mode_t Format
Unix uses bits 14-12 for file type:
S_IFDIR(0o040000) - DirectoryS_IFREG(0o100000) - Regular fileS_IFLNK(0o120000) - Symbolic link- And others (FIFO, socket, device)
Permissions are stored in the lower 12 bits (0o7777).
Go os.FileMode Format
Go uses high bits for file type flags:
- Bit 31 (0x80000000) - Directory
- Bit 27 (0x08000000) - Symbolic link
- Bit 26 (0x04000000) - Device
- And others
Regular files have no special type bit set.
Conversion Mapping
| Unix Type | Octal | Go Mode | Hex |
|---|---|---|---|
| Regular file | 0o100000 | (none) | 0x00000000 |
| Directory | 0o040000 | ModeDir | 0x80000000 |
| Symlink | 0o120000 | ModeSymlink | 0x08000000 |
| Named pipe | 0o010000 | ModeNamedPipe | 0x02000000 |
| Socket | 0o140000 | ModeSocket | 0x01000000 |
Special permission bits (setuid, setgid, sticky) are also converted appropriately.
Supported File Types
- ✅ Regular files
- ✅ Directories
- ✅ Symbolic links
- ✅ Named pipes (FIFO)
- ✅ Sockets
- ✅ Character devices
- ✅ Block devices
- ✅ Special permission bits (setuid, setgid, sticky)
Why This Crate?
When building systems that interact with both Rust and Go code (like container build systems), you often need to serialize file metadata in a way that Go can understand. Direct conversion of Unix mode_t values to Go's FileMode format requires careful bit manipulation. This crate handles all the edge cases correctly.
Use Cases
- Building gRPC services that communicate with Go-based systems
- Container build tools (BuildKit, Docker)
- File synchronization protocols (fsutil)
- Any system bridging Rust and Go file handling
Performance
All conversion functions are marked #[inline] and compile down to simple bit operations. There is zero runtime overhead compared to manual bit manipulation.
License
This project is licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Related Projects
- buildkit-client - Rust client for BuildKit
- BuildKit - Concurrent, cache-efficient build toolkit