
Predicate.pudu
Pudu111 lines3.4 KB
1/** @Resilience.Predicate.Module — which outcomes a reactive strategy handles */2module PuduLangResilience.Predicate34import PuduLangResilience.Context as Context5import PuduLangResilience as Resilience67/** @Resilience.Predicate.Arguments — the outcome being judged and where it arose */8export type Arguments[T, E] = { outcome: Resilience.Outcome[T, E], context: Context.Context, attempt: Int }910/** @Resilience.Predicate.Predicate — answers whether a strategy handles an outcome */11export type Predicate[T, E] = fn(Arguments[T, E]) -> Bool121314export fn arguments[T, E](outcome: Resilience.Outcome[T, E], context: Context.Context, attempt: Int) -> Arguments[T, E] {15 Arguments{outcome: outcome, context: context, attempt: attempt}16}171819export fn handles[T, E](test: &Predicate[T, E], given: &Arguments[T, E]) -> Bool { (*test)(*given) }202122export fn failures[T, E]() -> Predicate[T, E] {23 fn(given: Arguments[T, E]) -> Bool {24 match given.outcome {25 case Ok(_) => false26 case Err(found) => !Resilience.isCancellation(&found)27 }28 }29}303132export fn raised[T, E](test: fn(E) -> Bool) -> Predicate[T, E] {33 fn(given: Arguments[T, E]) -> Bool {34 match given.outcome {35 case Err(Resilience.Raised(problem)) => test(problem)36 case _ => false37 }38 }39}404142export fn anyRaised[T, E]() -> Predicate[T, E] { raised(fn(_problem: E) -> Bool { true }) }434445export fn failure[T, E](test: fn(Resilience.Failure[E]) -> Bool) -> Predicate[T, E] {46 fn(given: Arguments[T, E]) -> Bool {47 match given.outcome {48 case Err(found) => test(found)49 case Ok(_) => false50 }51 }52}535455export fn results[T, E](test: fn(T) -> Bool) -> Predicate[T, E] {56 fn(given: Arguments[T, E]) -> Bool {57 match given.outcome {58 case Ok(value) => test(value)59 case Err(_) => false60 }61 }62}636465export fn result[T, E](expected: T) -> Predicate[T, E] { results(fn(value: T) -> Bool { value == expected }) }666768export fn timeouts[T, E]() -> Predicate[T, E] {69 failure(fn(found: Resilience.Failure[E]) -> Bool {70 match found {71 case Resilience.TimedOut(_) => true72 case _ => false73 }74 })75}767778export fn brokenCircuits[T, E]() -> Predicate[T, E] {79 failure(fn(found: Resilience.Failure[E]) -> Bool {80 match found {81 case Resilience.BrokenCircuit(_) => true82 case Resilience.IsolatedCircuit => true83 case _ => false84 }85 })86}878889export fn rateLimited[T, E]() -> Predicate[T, E] {90 failure(fn(found: Resilience.Failure[E]) -> Bool {91 match found {92 case Resilience.RateLimited(_) => true93 case _ => false94 }95 })96}979899export fn anyOf[T, E](tests: &Array[Predicate[T, E]]) -> Predicate[T, E] {100 let all = *tests101 fn(given: Arguments[T, E]) -> Bool {102 for test in all {103 if test(given) { return true }104 }105 false106 }107}108109110export fn never[T, E]() -> Predicate[T, E] { fn(_given: Arguments[T, E]) -> Bool { false } }111