Internal Architecture
This document explains the internal architecture and organization of the darwin-metrics
codebase.
Project Structure
The darwin-metrics library follows a domain-driven design approach, organizing code around system resources:
darwin-metrics/
├── Cargo.lock
├── Cargo.toml # Crate configuration
├── LICENSE
├── NOTICE
├── README.md # Project overview
├── build.rs # Native code build script
├── changelog-configuration.json # Release configuration
├── clippy.toml # Linting configuration
├── coverage/ # Code coverage reports
├── docs/ # Documentation
│ ├── CHANGELOG.md # Release history
│ ├── CHECKLIST.md # Release checklist
│ ├── ROADMAP.md # Development roadmap
│ ├── RUST_API_CHECKLIST.md # API design guidelines
│ ├── TODO.md # Development tasks
│ ├── book.toml # mdBook configuration
│ ├── book/ # Generated documentation
│ ├── custom.css # Documentation styling
│ └── src/ # Documentation source
│ ├── SUMMARY.md # Documentation index
│ ├── advanced/ # Advanced topics
│ ├── development/ # Developer guides
│ ├── getting-started.md # Quickstart guide
│ ├── introduction.md # Project introduction
│ └── modules/ # Module documentation
├── examples/ # Example applications
│ ├── disk_monitor.rs # Disk monitoring example
│ ├── gpu_monitor_safe.rs # Safe GPU monitoring
│ ├── gpu_monitor_simplified.rs # Simplified GPU example
│ ├── gpu_static.rs # Static GPU info example
│ ├── memory_monitor.rs # Memory monitoring
│ ├── memory_monitor_async.rs # Async memory monitoring
│ ├── network_async.rs # Async network monitoring
│ └── network_info.rs # Network info example
├── src/ # Main source code
│ ├── battery/ # Battery monitoring
│ │ └── mod.rs # Battery module implementation
│ ├── disk/ # Disk monitoring
│ │ └── mod.rs # Disk module implementation
│ ├── docs_rs_stubs.rs # Support for docs.rs
│ ├── error.rs # Error handling
│ ├── hardware/ # Hardware-related modules
│ │ ├── cpu/ # CPU metrics
│ │ │ ├── cpu_impl.rs # CPU implementation
│ │ │ ├── frequency.rs # CPU frequency tracking
│ │ │ └── mod.rs # CPU module definition
│ │ ├── gpu/ # GPU metrics
│ │ │ └── mod.rs # GPU implementation
│ │ ├── iokit/ # IOKit interface
│ │ │ ├── mock.rs # Mock implementation for testing
│ │ │ ├── mod.rs # Main implementation
│ │ │ └── tests.rs # Tests for IOKit
│ │ ├── memory/ # Memory metrics
│ │ │ └── mod.rs # Memory implementation
│ │ ├── mod.rs # Hardware module exports
│ │ └── temperature/ # Temperature sensors
│ │ └── mod.rs # Temperature implementation
│ ├── lib.rs # Library entry point
│ ├── network/ # Network monitoring
│ │ ├── interface.rs # Network interfaces
│ │ ├── mod.rs # Network module exports
│ │ └── traffic.rs # Network traffic
│ ├── power/ # Power management
│ │ └── mod.rs # Power implementation
│ ├── process/ # Process monitoring
│ │ └── mod.rs # Process implementation
│ ├── resource/ # Resource monitoring
│ │ └── mod.rs # Resource implementation
│ ├── system/ # System information
│ │ └── mod.rs # System implementation
│ └── utils/ # Utility functions
│ ├── bindings.rs # FFI bindings
│ ├── mod.rs # Utilities exports
│ ├── property_utils.rs # Property access utilities
│ ├── property_utils_tests.rs # Tests for property utils
│ └── test_utils.rs # Testing utilities
└── tests/ # Integration tests
└── version-sync.rs # Version consistency tests
Core Design Principles
1. Module Independence
Each module is designed to function independently while relying on shared utilities. This allows:
- Using only the features you need
- Minimizing dependency chain issues
- Isolated testing without the entire library
2. Layered Architecture
The codebase follows a layered approach:
+-----------------------------------------+
| Public API (lib.rs) |
+-----------------------------------------+
| Domain-specific Modules |
| (cpu, memory, process, etc.) |
+-----------------------------------------+
| Shared Utilities |
| (error handling, FFI helpers) |
+-----------------------------------------+
| FFI Layer |
| (bindings.rs, unsafe code) |
+-----------------------------------------+
3. FFI Strategy
Foreign Function Interface (FFI) calls to macOS APIs are centralized in src/utils/bindings.rs
. This design:
- Contains unsafe code in a single location
- Promotes code reuse across modules
- Makes the codebase easier to audit
- Simplifies maintenance of platform-specific code
Error Handling
The library uses a consistent error handling approach:
- A centralized
Error
enum insrc/error.rs
- Module-specific error variants
- The
Result<T, Error>
type alias for function returns - Use of
thiserror
for error derivation
Example:
use thiserror::Error;
#[derive(Debug, Error)]
pub enum Error {
#[error("System error: {0}")]
System(String),
#[error("Process error: {0}")]
Process(String),
#[error("Resource not available: {0}")]
NotAvailable(String),
// ... other error variants
}
pub type Result<T> = std::result::Result<T, Error>;
Testing Strategy
The codebase uses multiple testing approaches:
- Unit Tests: Focused on isolated functionality
- Integration Tests: Testing module interactions
- Mock Objects: For simulating hardware components
- Conditional Testing: Platform-specific test cases
Test utilities in src/utils/test_utils.rs
provide common testing functionality.
Platform Compatibility
While the library targets macOS specifically:
- Platform checks ensure proper behavior
- API stability is maintained across macOS versions
- Version-specific code is isolated when needed
- Fallback mechanisms handle API differences