opt!() { /* proc-macro */ }Expand description
A procedural macro for safe optional chaining in Rust.
The opt! macro provides a concise syntax for chaining operations on Option and Result types,
similar to optional chaining in languages like TypeScript or Swift. It automatically handles
unwrapping and propagates None values through the chain.
§Syntax
The macro supports several operators for different use cases:
?.- Unwraps anOption, returnsNoneif the value isNone?Ok.- Unwraps aResultto itsOkvariant, returnsNoneifErr?Err.- Unwraps aResultto itsErrvariant, returnsNoneifOk.field- Access a field without unwrapping (for required fields)
The macro returns Some(value) if all operations succeed, or None if any step fails.
§Examples
§Basic Option chaining
ⓘ
use option_chain_tool::opt;
struct User {
profile: Option<Profile>,
}
struct Profile {
address: Option<Address>,
}
struct Address {
city: Option<String>,
}
let user = User {
profile: Some(Profile {
address: Some(Address {
city: Some("New York".to_string()),
}),
}),
};
// Instead of: user.profile.as_ref().and_then(|p| p.address.as_ref()).and_then(|a| a.city.as_ref())
let city: Option<&String> = opt!(user.profile?.address?.city?);
assert_eq!(city, Some(&"New York".to_string()));§Chaining with method calls
ⓘ
use option_chain_tool::opt;
impl Address {
fn get_city(&self) -> Option<&String> {
self.city.as_ref()
}
}
let city: Option<&String> = opt!(user.profile?.address?.get_city()?);§Accessing required fields
ⓘ
use option_chain_tool::opt;
struct Address {
city: Option<String>,
street: String, // Required field
}
// Access a required field in the chain (no ? after street)
let street: Option<&String> = opt!(user.profile?.address?.street);§Working with Result types
ⓘ
use option_chain_tool::opt;
struct Address {
validation: Result<String, String>,
}
// Extract the Ok variant
let ok_value: Option<&String> = opt!(user.profile?.address?.validation?Ok);
// Extract the Err variant
let err_value: Option<&String> = opt!(user.profile?.address?.validation?Err);§Complex chaining
ⓘ
use option_chain_tool::opt;
// Combine multiple patterns in a single chain
let value: Option<&String> = opt!(
user
.profile? // Unwrap Option<Profile>
.address? // Unwrap Option<Address>
.street // Access required field
.validation?Ok // Unwrap Result to Ok variant
);§Returns
Some(value)if all operations in the chain succeedNoneif any operation in the chain returnsNoneor encounters an unwrappable value
§Notes
The macro generates nested if let expressions that short-circuit on None, providing
efficient and safe optional chaining without runtime panics.