Repository navigation
Getting Started
Install Pudu 0.1.3 or later, then create a project and add the package:
pudu init my-app
cd my-app
pudu install @chrismichaelps/pudu-lang-mediator@0.1.0A message has a kind: a typed value naming what is sent (GetPrice), what it answers (Int),
and what its handler fails with (Str). You make each kind once, register a handler for it, and
build a mediator from the registrations. Sending a request runs its handler and answers an
Outcome, which is Result with the error side fixed to Failure:
module Ex01First
import Std.Io as Io
import PuduLangMediator.Context as Context
import PuduLangMediator.Mediator as Mediator
import PuduLangMediator as Messaging
import PuduLangMediator.Registration as Registration
import PuduLangMediator.Request as Request
type GetPrice = { item: Str }
fn shop(getPrice: &Request.Kind[GetPrice, Int, Str]) -> Mediator.Mediator {
let built = Mediator.build([
Registration.handler(getPrice, fn(request: GetPrice, _context: Context.Context) -> Messaging.Outcome[Int, Str] {
if request.item == "tea" { Ok(4) } else { Messaging.raise("no price for " + request.item) }
})
])
match built {
case Ok(mediator) => mediator
case Err(invalid) => panic(Mediator.explain(&invalid))
}
}
export fn main() -> Int {
let getPrice: Request.Kind[GetPrice, Int, Str] = Request.kind("prices.get")
let mediator = shop(&getPrice)
let tea = Mediator.send(&mediator, &getPrice, GetPrice{item: "tea"})
let gold = Mediator.send(&mediator, &getPrice, GetPrice{item: "gold"})
let _first = Io.writeLine("tea: " + Messaging.summarize(&tea))
let _second = Io.writeLine("gold: " + Messaging.summarize(&gold))
if tea == Ok(4) && gold == Err(Messaging.Raised("no price for gold")) { 0 } else { 1 }
}
Check it and run it:
pudu check src/Ex01First.pudu
pudu run src/Ex01First.puduOutput:
tea: Ok(4)
gold: The handler failed: "no price for gold"
Request.kind makes a request kind; Registration.handler pairs it with the function that
answers it. Mediator.build takes every registration as one flat array and either answers the
mediator or every problem it found, which Mediator.explain puts in one sentence. A handler's own
error comes back as Raised, and Messaging.summarize renders any outcome in one line. An exported
main returning Int sets the process exit status.
Make kinds once at startup and pass them around with the mediator: two kinds made by separate calls under one name are different kinds, and the mediator tells them apart.