Control Flow
Cambrian provides two control flow expressions: if/else for conditional
branching and match for pattern matching. Both are expressions – they
evaluate to a value.
if / else
The if/else expression evaluates a boolean condition and returns the value
of the corresponding branch:
let fee = if amount > threshold { high_fee } else { low_fee };
Basic Form
if condition {
value_when_true
} else {
value_when_false
}
Both branches must produce values of the same type when used as an expression.
Chained Conditions
Multiple conditions can be chained with else if:
let tier = if amount >= 10000 {
"gold"
} else if amount >= 1000 {
"silver"
} else {
"bronze"
};
In Member Transforms
if/else is frequently used in member transforms to compute new state
conditionally:
m_high_score: u64 {
in submit(score) => if score > m_high_score {
score
} else {
m_high_score
}
}
In Pure Functions
Pure functions commonly use if/else as their body:
pure fn max(a: u64, b: u64) -> u64 {
if a >= b { a } else { b }
}
pure fn clamp(val: u64, lo: u64, hi: u64) -> u64 {
if val < lo { lo }
else if val > hi { hi }
else { val }
}
match
The match expression compares a value against a series of patterns and
executes the first matching branch:
let description = match status {
Status::Active => "running",
Status::Paused => "paused",
Status::Closed => "finished",
_ => "unknown"
};
Syntax
match expression {
Pattern1 => result1,
Pattern2 => result2,
_ => default_result
}
Each arm consists of a pattern, the => arrow, and a result expression.
Arms are separated by commas.
Matching Enum Variants
The most common use of match is destructuring enums:
enum Command {
Deposit(U256),
Withdraw(U256),
Freeze
}
let response = match cmd {
Command::Deposit(amount) => amount,
Command::Withdraw(amount) => amount,
Command::Freeze => 0
};
The variable names in data variant patterns (like amount above) bind the
associated data for use in the result expression.
Matching Option
Option<T> is commonly matched to handle present and absent values:
let balance = match m_balances.get(account) {
some(val) => val,
none => 0
};
Block Bodies
When a match arm needs multiple computations, use a block:
let result = match action {
Action::Transfer(to, amount) => {
let fee = amount * 3 / 100;
amount - fee
},
Action::Refund(amount) => amount,
_ => 0
};
Wildcard Pattern
The _ pattern matches any value. It is typically used as the last arm to
handle all remaining cases:
match value {
0 => "zero",
1 => "one",
_ => "other"
}
In Route Actions
match can be used inside route actions for conditional dispatch:
routes {
execute(action: Action) => [
match action {
Action::Transfer(amount) => [
~> m_recipient with { value: amount }
],
Action::Pause => []
}
]
}
Exhaustiveness
The compiler checks that match expressions cover all possible variants when
matching on an enum. If any variant is missing and no wildcard _ arm is
present, the compiler will report an error. This guarantees that no case is
accidentally overlooked.