Conditional Compilation with Feature Flags in Rust
Conditional compilation allows you to include or exclude code based on certain conditions at compile time. This is incredibly useful for enabling/disabling features, targeting different platforms, or including debugging code only in development builds. This challenge will guide you through implementing conditional compilation in Rust using feature flags.
Problem Description
You are tasked with creating a Rust library that provides a simple logging functionality. This library should have a feature flag named detailed_logging that, when enabled, adds extra verbose logging statements. When disabled (the default), these verbose statements should be completely removed from the compiled code, reducing the binary size and potentially improving performance.
Specifically, you need to:
- Create a new Rust library project.
- Define a feature flag named
detailed_loggingin yourCargo.tomlfile. - Implement a
logfunction that takes a message string as input. - When the
detailed_loggingfeature is enabled, thelogfunction should print the current timestamp along with the message. When the feature is disabled, it should only print the message. - Provide a
mainfunction (insrc/main.rsif you choose to create an executable, or in a test file) to demonstrate the usage of thelogfunction with and without thedetailed_loggingfeature enabled.
Key Requirements:
- The code should compile and run correctly with and without the
detailed_loggingfeature enabled. - The verbose logging statements should be completely removed from the compiled binary when the feature is disabled. This means they shouldn't even be present in the executable.
- The
logfunction should be part of a public module. - The timestamp format should be
YYYY-MM-DD HH:MM:SS.
Expected Behavior:
- Without
detailed_logging: Thelogfunction should only print the message string. - With
detailed_logging: Thelogfunction should print the current timestamp followed by a space, and then the message string.
Edge Cases to Consider:
- Ensure the timestamp format is consistent.
- Consider how the timestamp is obtained (e.g., using
chronocrate). - Test both compilation and runtime behavior with and without the feature flag.
Examples
Example 1:
Cargo.toml (with detailed_logging enabled):
[features]
detailed_logging = []
src/lib.rs:
#[cfg(feature = "detailed_logging")]
use chrono::Local;
pub mod logger {
#[cfg(feature = "detailed_logging")]
pub fn log(message: &str) {
let now = Local::now();
let timestamp = now.format("%Y-%m-%d %H:%M:%S").to_string();
println!("{}: {}", timestamp, message);
}
#[cfg(not(feature = "detailed_logging"))]
pub fn log(message: &str) {
println!("{}", message);
}
}
src/main.rs:
fn main() {
logger::log("This is a log message.");
}
Output:
2023-10-27 10:30:00: This is a log message. (Timestamp will vary)
Example 2:
Cargo.toml (without detailed_logging enabled):
[features]
detailed_logging = []
src/lib.rs:
#[cfg(feature = "detailed_logging")]
use chrono::Local;
pub mod logger {
#[cfg(feature = "detailed_logging")]
pub fn log(message: &str) {
let now = Local::now();
let timestamp = now.format("%Y-%m-%d %H:%M:%S").to_string();
println!("{}: {}", timestamp, message);
}
#[cfg(not(feature = "detailed_logging"))]
pub fn log(message: &str) {
println!("{}", message);
}
}
src/main.rs:
fn main() {
logger::log("This is a log message.");
}
Output:
This is a log message.
Constraints
- The solution must use feature flags for conditional compilation.
- The timestamp format must be
YYYY-MM-DD HH:MM:SS. - The
chronocrate is allowed for timestamp generation. - The solution should compile and run without errors.
- The verbose logging statements must be completely removed when the feature flag is disabled.
Notes
- Consider using the
#[cfg(feature = "...")]attribute to conditionally compile code based on the presence of a feature flag. - The
chronocrate needs to be added as a dependency in yourCargo.tomlif you choose to use it. - Think about how to structure your code to keep the conditional logic clean and maintainable. Using a module is recommended.
- Test your solution thoroughly with both the feature flag enabled and disabled to ensure it behaves as expected.
cargo build --features detailed_loggingandcargo buildare your friends.