Switch (Multiple Conditions)
Handle multiple mutually exclusive conditions with pattern matching.
Basic Pattern Matching
enum Status {
Pending
Active
Completed
Error(String)
}
fn status_badge(status : Status) -> @luna.Node {
match status {
Pending => span(class_="yellow", [text("Pending")])
Active => span(class_="green", [text("Active")])
Completed => span(class_="blue", [text("Completed")])
Error(msg) => span(class_="red", [text("Error: " + msg)])
}
}
String Matching
fn tab_content(tab : String) -> @luna.Node {
match tab {
"overview" => overview_panel()
"details" => details_panel()
"reviews" => reviews_panel()
_ => div([text("Unknown tab")])
}
}
Number Ranges
fn grade_label(score : Int) -> @luna.Node {
let grade = if score >= 90 {
"A"
} else if score >= 80 {
"B"
} else if score >= 70 {
"C"
} else if score >= 60 {
"D"
} else {
"F"
}
span([text(grade)])
}
Option Pattern
fn user_display(user : Option[User]) -> @luna.Node {
match user {
Some(u) => div([
h2([text(u.name)]),
p([text(u.email)])
])
None => div([text("No user selected")])
}
}
Result Pattern
fn data_display(result : Result[Data, String]) -> @luna.Node {
match result {
Ok(data) => data_view(data)
Err(msg) => error_view(msg)
}
}
Nested Pattern Matching
enum LoadState[T] {
Idle
Loading
Success(T)
Error(String)
}
fn async_content[T](state : LoadState[T], render : (T) -> @luna.Node) -> @luna.Node {
match state {
Idle => div([text("Ready to load")])
Loading => div(class_="spinner", [text("Loading...")])
Success(data) => render(data)
Error(msg) => div(class_="error", [
h3([text("Error")]),
p([text(msg)])
])
}
}
Multiple Conditions
struct Filters {
category : Option[String]
price_range : Option[(Int, Int)]
in_stock : Bool
}
fn filter_description(filters : Filters) -> @luna.Node {
let parts = []
match filters.category {
Some(cat) => parts.push("Category: " + cat)
None => ()
}
match filters.price_range {
Some((min, max)) => parts.push("Price: $" + min.to_string() + "-$" + max.to_string())
None => ()
}
if filters.in_stock {
parts.push("In stock only")
}
if parts.length() == 0 {
p([text("No filters applied")])
} else {
ul(parts.map(fn(p) { li([text(p)]) }))
}
}
Comparison with TypeScript
TypeScript uses <Switch> and <Match> components:
// TypeScript
<Switch fallback={<Default />}>
<Match when={status() === "loading"}>
<Loading />
</Match>
<Match when={status() === "error"}>
<Error />
</Match>
</Switch>
MoonBit uses pattern matching:
// MoonBit
match status {
Loading => loading_view()
Error(msg) => error_view(msg)
_ => default_view()
}
Try It
Create a traffic light component:
Define a
Lightenum with Red, Yellow, GreenRender different colors for each state
Add a description text for each state
Next
Learn about onMount โ