~/bend-docscommunity

opts.bend source

opts.bend on the hub · documented module

# What a program says to a session and what a session says back when it# fails: the options, and errors with a reason. Pure: the laws hold them.import Base# Options# -------# url: the stream's address. user, pass: the login, when it is not in# the URL. wait: how long, in ms, the server may stay silent. audio:# whether to ask for the audio too. ca: a PEM file to check a TLS# server's certificate against, "" for the system's store.type Opts is Data:  Opts{url: String, user: String, pass: String, wait: U32, audio: Bool, ca: String}def Opts.new(url: String) -> Opts:  Opts{url, "", "", 10000, True{}, ""}def Opts.login(o: Opts, user: String, pass: String) -> Opts:  Opts{url, _, _, wait, audio, ca} = o  Opts{url, user, pass, wait, audio, ca}def Opts.wait(o: Opts, ms: U32) -> Opts:  Opts{url, user, pass, _, audio, ca} = o  Opts{url, user, pass, ms, audio, ca}def Opts.audio(o: Opts, yes: Bool) -> Opts:  Opts{url, user, pass, wait, _, ca} = o  Opts{url, user, pass, wait, yes, ca}def Opts.ca(o: Opts, path: String) -> Opts:  Opts{url, user, pass, wait, audio, _} = o  Opts{url, user, pass, wait, audio, path}# The same options for another address.def Opts.to(o: Opts, url: String) -> Opts:  Opts{_, user, pass, wait, audio, ca} = o  Opts{url, user, pass, wait, audio, ca}def Opts.wait.of(o: Opts) -> U32:  Opts{_, _, _, w, _, _} = o  wdef Opts.url(o: Opts) -> String:  Opts{u, _, _, _, _, _} = o  udef Opts.ca.of(o: Opts) -> String:  Opts{_, _, _, _, _, c} = o  c# Errors# ------# Why something failed, for a program to act on: try again later# (NoRoute, Silent, Hangup), ask for another password (NoLogin), give up# (NoStream, Unsafe, Refused, Garbled, BadUrl). Ended is no failure:# the stream came to its end. Moved is what a redirect is inside the# client, its words the new address; open follows it, so a program sees# it only after too many in a row.type Why is Data:  NoRoute{}  Unsafe{}  NoLogin{}  NoStream{}  Silent{}  Hangup{}  Refused{}  Garbled{}  BadUrl{}  Ended{}  Moved{}# An error: why, the system's or the server's code (0 for none), and# words for a person.type Err is Data:  Err{why: Why, code: U32, msg: String}def Why.name(w: Why) -> String:  match w:    case NoRoute{}:      "cannot connect"    case Unsafe{}:      "TLS failed"    case NoLogin{}:      "login refused"    case NoStream{}:      "no such stream"    case Silent{}:      "timed out"    case Hangup{}:      "connection closed"    case Refused{}:      "refused"    case Garbled{}:      "protocol error"    case BadUrl{}:      "bad URL"    case Ended{}:      "stream ended"    case Moved{}:      "moved"def Why.ended(w: Why) -> Bool:  match w:    case Ended{}:      True{}    case _:      False{}# Whether opening again may work: the network or the server faltered# (NoRoute, Silent, Hangup), as against an answer that will not change.def Why.again(w: Why) -> Bool:  match w:    case NoRoute{}:      True{}    case Silent{}:      True{}    case Hangup{}:      True{}    case _:      False{}# Whether no amount of waiting will help: the login, the certificate or# the URL is wrong. Anything else may pass once a stream that was# flowing comes back (a server that restarts has no stream for a while).def Why.lasting(w: Why) -> Bool:  match w:    case NoLogin{}:      True{}    case Unsafe{}:      True{}    case BadUrl{}:      True{}    case _:      False{}def Err.lasting(e: Err) -> Bool:  Err{why, _, _} = e  Why.lasting(why)def Err.moved(e: Err) -> Bool:  Err{why, _, _} = e  match why:    case Moved{}:      True{}    case _:      False{}def Err.again(e: Err) -> Bool:  Err{why, _, _} = e  Why.again(why)# An error in a line: "login refused (401): wrong user or password".def Err.show(e: Err) -> String:  Err{why, +code, msg} = e  Why.name(why) ++ Bool.pick(String, U32.is_zero(code), "", " (" ++ U32.show(code) ++ ")")    ++ ": " ++ msg