src/step.bend

ezsys@0.1.0.0 · 61 lines · 9 definitions

1# ezsys/src/step: every decision the file and environment helpers make. It
2# does no IO; src/sys.bend runs the effects and acts on these answers
3# (SYS-TRUST-4).
4import Base
5
6# after one read: read again with the text so far, or stop with an answer
7type Read is Type:
8  ReadMore{text: String}
9  ReadStop{answer: Result<&1, &1, U32 & String, String>}
10
11# after the temporary file is written: rename it, or stop with a failure
12type Save is Type:
13  SaveMove{}
14  SaveStop{error: U32 & String}
15
16# the bytes one read asks for: the file's size, and at least 64 KiB
17def read.chunk(size: U32) -> U32:
18  U32.max(size, 65536)
19
20# a chunk that is empty ends the file; any other is appended
21def read.more(empty: Bool, text: String, got: String) -> Read:
22  match empty:
23    case True{}:
24      ReadStop{Done{got}}
25    case False{}:
26      ReadMore{got ++ text}
27
28# what one read's answer means, with the text read before it
29def read.step(res: Result<&1, &1, U32 & String, String>, got: String) -> Read:
30  match res:
31    case Fail{error}:
32      ReadStop{Fail{error}}
33    case Done{+text}:
34      read.more(String.is_empty(text), text, got)
35
36# the answer when a file has not ended after every read file.read makes
37def read.spent() -> Result<&1, &1, U32 & String, String>:
38  Fail{(27, "ezsys: file.read: the file did not end")}
39
40# where file.save writes before it renames
41def save.tmp(path: String) -> String:
42  path ++ ".tmp"
43
44# what the temporary file's write answer means
45def save.step(res: Result<&1, &1, U32 & String, Unit>) -> Save:
46  match res:
47    case Fail{error}:
48      SaveStop{error}
49    case Done{_u}:
50      SaveMove{}
51
52# an environment variable's value, or the fallback when it is unset
53def env.pick(
54  res: Result<&1, &1, U32 & String, String>,
55  fallback: String
56) -> String:
57  match res:
58    case Fail{_error}:
59      fallback
60    case Done{value}:
61      value