
Message.pudu
Pudu83 lines3.3 KB
1/** @Mediator.Message.Vocabulary — what every kind of message shares */2module PuduLangMediator.Message34import PuduLangMediator as Messaging5import PuduLangMediator.Utils.Erasure as Erasure67/** @Mediator.Message.Shape — a request with or without a response, a notification, or a stream */8export type Shape = Query | Command | Event | Sequence910/** @Mediator.Message.Info — the name, shape, and tags of one kind */11export type Info = { name: Str, shape: Shape, tags: Array[Str] }1213/** @Mediator.Message.Envelope — a message whose type the sender does not name */14export type Envelope = { info: Info, packed: Erasure.Packed, summary: Str }1516/** @Mediator.Message.Fault — why an envelope reached no handler */17export type Fault = NoRoute(Str) | WrongKind(Str)1819/** @Mediator.Message.Delivery — the outcome of an envelope, why there is none, or no listener */20export type Delivery = Delivered(Erasure.Packed) | Undelivered(Fault) | Unheard2122/** @Mediator.Message.Answer — what an envelope's handler answered */23export type Answer = { info: Info, delivery: Delivery, failed: Bool, summary: Str }242526export fn hasTag(info: &Info, tag: Str) -> Bool { info.tags.contains(tag) }272829export fn shapeName(shape: &Shape) -> Str {30 match shape {31 case Query => "query"32 case Command => "command"33 case Event => "event"34 case Sequence => "sequence"35 }36}373839export fn failureOf[E](fault: &Fault) -> Messaging.Failure[E] {40 match fault {41 case NoRoute(name) => Messaging.Unhandled(name)42 case WrongKind(name) => Messaging.Mismatched(name)43 }44}454647export fn answered[T, E](info: &Info, outcomes: &Erasure.Slot[Messaging.Outcome[T, E]], outcome: Messaging.Outcome[T, E]) -> Answer {48 let failed = match outcome {49 case Ok(_) => false50 case Err(_) => true51 }52 let summary = Messaging.summarize(&outcome)53 Answer{info: *info, delivery: Delivered(Erasure.pack(outcomes, outcome)), failed: failed, summary: summary}54}555657export fn undelivered(info: &Info, fault: Fault) -> Answer {58 let failure: Messaging.Failure[Str] = failureOf(&fault)59 Answer{info: *info, delivery: Undelivered(fault), failed: true, summary: Messaging.describe(&failure)}60}616263export fn unheard(info: &Info) -> Answer {64 let quiet: Messaging.Outcome[(), Str] = Ok(())65 Answer{info: *info, delivery: Unheard, failed: false, summary: Messaging.summarize(&quiet)}66}67686970export fn read[T, E](outcomes: &Erasure.Slot[Messaging.Outcome[T, E]], answer: &Answer) -> Option[Messaging.Outcome[T, E]] {71 match answer.delivery {72 case Delivered(packed) => Erasure.unpack(outcomes, &packed)73 case Undelivered(fault) => Some(Err(failureOf(&fault)))74 case Unheard => None75 }76}777879export fn sealed[M](info: &Info, messages: &Erasure.Slot[M], message: M) -> Envelope {80 let summary = show(message)81 Envelope{info: *info, packed: Erasure.pack(messages, message), summary: summary}82}83