Turn ? into .unwrap() Behind a Feature
As explained in Method, with the consume-question feature enabled, appending ! to the method allows consuming ?.
We can use this to treat ? as an alias for .unwrap().
Example: when an unwrap feature is enabled, replace ? with .unwrap(). Cargo.toml features:
[dependencies]
hooq = { version = "*", features = ["consume-question"] }
# ..
[features]
unwrap = []
Prepare a flavor in hooq.toml. We restrict hook_targets to only ? so tails/returns are unaffected.
[unwrap]
method = """.unwrap()!"""
hook_targets = ["?"]
main.rs:
use hooq::hooq;
fn failable<T>(val: T) -> Result<T, String> {
Ok(val)
}
#[cfg_attr(not(feature = "unwrap"), hooq(empty))]
#[cfg_attr(feature = "unwrap", hooq(unwrap))]
fn process(flag: bool) -> Result<(), String> {
if flag {
return Err("An error occurred".into());
}
let _ = failable(42)?;
Ok(())
}
#[cfg_attr(not(feature = "unwrap"), hooq(empty))]
#[cfg_attr(feature = "unwrap", hooq(unwrap))]
fn main() -> Result<(), Box<dyn std::error::Error>> {
process(false)?;
Ok(())
}
Without the unwrap feature, expansion uses the empty flavor and nothing changes:
#![feature(prelude_import)]
#[macro_use]
extern crate std;
#[prelude_import]
use std::prelude::rust_2024::*;
use hooq::hooq;
fn failable<T>(val: T) -> Result<T, String> {
Ok(val)
}
fn process(flag: bool) -> Result<(), String> {
if flag {
return Err("An error occurred".into());
}
let _ = failable(42)?;
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
process(false)?;
Ok(())
}
With the unwrap feature, expansion replaces with .unwrap():
#![feature(prelude_import)]
#[macro_use]
extern crate std;
#[prelude_import]
use std::prelude::rust_2024::*;
use hooq::hooq;
fn failable<T>(val: T) -> Result<T, String> {
Ok(val)
}
fn process(flag: bool) -> Result<(), String> {
if flag {
return Err("An error occurred".into());
}
let _ = failable(42).unwrap();
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
process(false).unwrap();
Ok(())
}
Highlights:
- You can replace
?with special behaviors like.unwrap(). - Feature‑gated
#[cfg_attr(..., hooq(...))]lets you vary hooks by build configuration.