1 # ezhttp/src/body: request entity as empty, UTF-8 text, or octet list. Core does 2 # not depend on ezjson. Callers plug encode/decode through Bend type 3 # parameters (BYO JSON or any other representation). 4 import Base 5 6 # what rides in a request: nothing, text, or raw octets (each U32 is 0..255) 7 type Body is Data: 8 Empty{} 9 Text{text: String} 10 Octets{bytes: List<&2, U32>} 11 12 # one octet as a character whose code point is that byte 13 def octet.char(+b: U32) -> Char: 14 Char.from_u32(b) 15 16 # octets as a string of those code points (wire UTF-8 length is utf8.len) 17 def octets.chars(bs: List<&2, U32>) -> String: 18 match bs: 19 case []: 20 "" 21 case h <> t: 22 SCon{octet.char(h), octets.chars(t)} 23 24 # the payload bytes as a Bend string for the request line/body 25 def body.payload(b: Body) -> String: 26 match b: 27 case Empty{}: 28 "" 29 case Text{text}: 30 text 31 case Octets{bytes}: 32 octets.chars(bytes) 33 34 # empty body 35 def body.empty() -> Body: 36 Empty{} 37 38 # UTF-8 text body 39 def body.text(s: String) -> Body: 40 Text{s} 41 42 # octet body (each element a wire-oriented code point 0..255) 43 def body.octets(bs: List<&2, U32>) -> Body: 44 Octets{bs} 45 46 # BYO encode: any value to a text body via the caller's encoder 47 def body.encode(~A: Data, ~to_text: A -> String, value: A) -> Body: 48 Text{to_text(value)} 49 50 # BYO decode: body text to a value via the caller's decoder 51 def body.decode(~A: Data, ~from_text: String -> Maybe<&2, A>, s: String) 52 -> Maybe<&2, A>: 53 from_text(s)