Syntactic sugar for writing associated type algebra with operator expressions.
Provides two macros:
output!: Expands operator expressions to associated type outputs#[op_result]: Transforms operator expressions in where clauses into trait bounds. Supports two syntaxes:(): IsDefined<{ ... }>and[(); ...]:
use op_result::op_result;
use op_result::output;
#[op_result]
fn add<T, U>(a: T, b: U) -> output!(T + U)
where
[(); T + U]:,
{
a + b
}
let result = add(1, 2);
assert_eq!(result, 3);Transforms output!(T + U) into <T as core::ops::Add<U>>::Output. Works recursively for nested expressions, preserving parentheses for operator precedence.
use op_result::op_result;
use op_result::output;
#[op_result]
fn add<T, U>(a: T, b: U) -> output!(T + U)
where
[(); T + U]:,
{
a + b
}
let result = add(1, 2);Transforms operator expressions in where clauses into trait bounds.
use op_result::op_result;
use op_result::output;
#[op_result]
fn example_sub<T, U>(a: T, b: U) -> output!(T - U - U)
where
[(); T - U - U]:,
U: Copy,
{
(a - b) - b
}The output type can be assigned using the = operator:
use op_result::op_result;
#[op_result]
fn example_output_assignment<T, U, V>(a: T, b: U) -> V
where
[(); T + U = V]:,
{
a + b
}Both [(); ...]: and (): IsDefined<{ ... }> syntaxes are supported.
You can control which syntaxes are processed using attribute parameters:
#[op_result]- Default: both syntaxes enabled, usesIsDefinedas the marker trait name#[op_result(any_syntax)]- Explicitly enable both syntaxes#[op_result(any_syntax, TraitName)]- Enable both syntaxes with a custom marker trait name#[op_result(marker_trait_syntax)]- Only process(): IsDefined<{ ... }>syntax#[op_result(marker_trait_syntax, TraitName)]- Only process marker trait syntax with a custom trait name#[op_result(well_formedness_syntax)]- Only process[(); ...]:syntax
The optional second parameter (trait name) defaults to IsDefined and is only valid with marker_trait_syntax or any_syntax.
All binary and unary operators from core::ops that have an associated Output type:
+→ [core::ops::Add]-→ [core::ops::Sub]*→ [core::ops::Mul]/→ [core::ops::Div]%→ [core::ops::Rem]&→ [core::ops::BitAnd]|→ [core::ops::BitOr]^→ [core::ops::BitXor]<<→ [core::ops::Shl]>>→ [core::ops::Shr]!→ [core::ops::Not] (unary operator)-→ [core::ops::Neg] (unary operator)
Licensed under either of Apache License, Version 2.0 or MIT license at your option.