| Crates.io | r-resources |
| lib.rs | r-resources |
| version | 0.7.6 |
| created_at | 2025-11-07 07:33:21.514696+00 |
| updated_at | 2025-11-10 14:41:53.255007+00 |
| description | Android-style resource management for Rust - compile-time type-safe resource access |
| homepage | |
| repository | https://github.com/Glubus/r-resources |
| max_upload_size | |
| id | 1921282 |
| size | 134,414 |
A Rust library inspired by Android/Kotlin's R system for managing resources at build time.
Stop scattering magic numbers across 12 files! Centralize all your constants, strings, colors, and configuration in one place. Modify them quickly without hunting through your codebase.
const - safe to use in multi-threaded contexts// Magic numbers scattered everywhere 😞
const MAX_RETRIES: i64 = 3; // main.rs
const TIMEOUT: i64 = 5000; // api.rs
const RATE: f64 = 0.75; // billing.rs
// ... 12 more files to update when changing a value
<!-- res/values.xml - One place to rule them all! -->
<int name="max_retries">3</int>
<int name="timeout_ms">5000</int>
<float name="rate">0.75</float>
// Access anywhere, type-safe, zero-cost
use r_resources::r;
let retries = r::MAX_RETRIES;
let timeout = r::TIMEOUT_MS;
string: String valuesint: Integer values (i64)float: Floating-point values (f64)bool: Boolean valuescolor: Color hex stringsurl: URL stringsdimension: Dimension values with units (e.g., "16dp", "24px")string-array: String arraysint-array: Integer arraysfloat-array: Float arraysAdd this to your Cargo.toml:
[build-dependencies]
r-resources = "0.7.6"
Note: r-resources is a build dependency, not a runtime dependency. It generates code at compile time. All XML files in the res/ directory are automatically loaded and merged.
Create res/values.xml at the root of your project:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">My Awesome App</string>
<int name="max_retries">3</int>
<float name="tax_rate">0.20</float>
<bool name="debug_mode">true</bool>
</resources>
use r_resources::r;
fn main() {
println!("App: {}", r::APP_NAME);
println!("Max retries: {}", r::MAX_RETRIES);
println!("Tax rate: {}%", r::TAX_RATE * 100.0);
}
Organize resources hierarchically:
<resources>
<ns name="auth">
<string name="title">Login</string>
<ns name="errors">
<string name="invalid_credentials">Invalid credentials</string>
</ns>
</ns>
<ns name="ui">
<ns name="colors">
<color name="primary">#3366FF</color>
</ns>
</ns>
</resources>
Access via type-organized modules:
use r_resources::string;
string::auth::TITLE
string::auth::errors::INVALID_CREDENTIALS
Access via Kotlin-style r:: module:
use r_resources::r;
r::auth::TITLE
r::auth::errors::INVALID_CREDENTIALS
r::ui::colors::PRIMARY
Resolve references at build-time:
<string name="base_url">https://api.example.com</string>
<string name="api_version">v2</string>
<string name="welcome_title">Welcome to @string/app_name!</string>
<string name="api_url_with_version">@string/base_url/@string/api_version</string>
Generated:
string::WELCOME_TITLE // "Welcome to My Awesome App!"
string::API_URL_WITH_VERSION // "https://api.example.com/v2"
All references are resolved at compile-time - no runtime concatenation!
Generate reusable functions with typed parameters:
<string name="greeting" template="Hello {name}, you have {count} messages!">
<param name="name" type="string"/>
<param name="count" type="int"/>
</string>
Generated:
string::greeting("Alice", 5) // "Hello Alice, you have 5 messages!"
Supports string, int, float, and bool parameter types.
Support for multiple XML files in the res/ directory:
res/
├── values.xml # Main resources
├── config.xml # Configuration
└── theme.xml # Theme-specific resources
All XML files in res/ are automatically loaded and merged at build time.
Use namespaces to organize by language - no need for locale-specific files:
<ns name="fr">
<string name="welcome">Bienvenue!</string>
</ns>
<ns name="en">
<string name="welcome">Welcome!</string>
</ns>
// Switch based on user locale
let welcome = if locale == "fr" {
r::fr::WELCOME
} else {
r::en::WELCOME
};
use r_resources::r;
// Root level resources
r::APP_NAME
r::MAX_RETRIES
// Namespaced resources
r::auth::TITLE
r::auth::errors::INVALID_CREDENTIALS
r::ui::colors::PRIMARY
use r_resources::*;
// Explicit type organization
string::APP_NAME
int::MAX_RETRIES
string::auth::TITLE
color::ui::colors::PRIMARY
Both patterns are equally performant - choose what fits your style!
All resources are const values, making them completely thread-safe:
use std::thread;
use r_resources::r;
// Safe to access from multiple threads
let handles: Vec<_> = (0..10)
.map(|_| {
thread::spawn(|| {
println!("App: {}", r::APP_NAME);
})
})
.collect();
Run the examples to see r-resources in action:
# Basic usage
cargo run --example basic_usage
# New resource types
cargo run --example v02_new_types
# Resource references
cargo run --example v03_references
# Namespaces
cargo run --example v05_ns
# String interpolation and templates
cargo run --example v06_concat
Centralize. Type-safe. Zero-cost.
res/ - modify quickly without searching your codebasePerfect for projects where you need to:
git clone https://github.com/Glubus/r-resources.git
cd r-resources
cargo build
cargo test
cargo fmt # Format code
cargo clippy # Lint code
cargo test # Run all tests
Licensed under either of:
at your option.