Hone logo
Hone
Problems

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:

  1. Create a new Rust library project.
  2. Define a feature flag named detailed_logging in your Cargo.toml file.
  3. Implement a log function that takes a message string as input.
  4. When the detailed_logging feature is enabled, the log function should print the current timestamp along with the message. When the feature is disabled, it should only print the message.
  5. Provide a main function (in src/main.rs if you choose to create an executable, or in a test file) to demonstrate the usage of the log function with and without the detailed_logging feature enabled.

Key Requirements:

  • The code should compile and run correctly with and without the detailed_logging feature 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 log function should be part of a public module.
  • The timestamp format should be YYYY-MM-DD HH:MM:SS.

Expected Behavior:

  • Without detailed_logging: The log function should only print the message string.
  • With detailed_logging: The log function 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 chrono crate).
  • 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 chrono crate 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 chrono crate needs to be added as a dependency in your Cargo.toml if 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_logging and cargo build are your friends.
Loading editor...
rust