src/dir.bend

ezsys@0.1.0.0 · 77 lines · 8 definitions

1# ezsys/src/dir: every decision dir.list makes. It does no IO; src/sys.bend
2# reads a directory's raw entry names with its own effect (SYS-TRUST-5) and
3# hands them here. The answer drops exactly "." and ".." and sorts the rest
4# ascending by String.order, which compares code points one by one: that is
5# the bytewise order of their UTF-8 encodings.
6import Base
7
8# whether a name is "." or ".."
9def dir.dot(+name: String) -> Bool:
10  Bool.or(String.eq(name, "."), String.eq(name, ".."))
11
12# name before next when it sorts first, else next and the rest with name put
13# in them
14def dir.insert.pick(
15  first: Bool,
16  +name: String,
17  +next: String,
18  +ys: List<&2, String>,
19  rest: Unit -> List<&2, String>
20) -> List<&2, String>:
21  match first:
22    case True{}:
23      Con{name, Con{next, ys}}
24    case False{}:
25      Con{next, rest(Unit{})}
26
27# a name put into a sorted list, before the first name it does not sort after
28def dir.insert(+name: String, xs: List<&2, String>) -> List<&2, String>:
29  match xs:
30    case Nil{}:
31      [name]
32    case Con{+next, +ys}:
33      dir.insert.pick(String.is_le(name, next), name, next, ys,
34        _u => dir.insert(name, ys))
35
36# a list sorted ascending by String.order (insertion sort)
37def dir.sort(xs: List<&2, String>) -> List<&2, String>:
38  match xs:
39    case Nil{}:
40      Nil{}
41    case Con{+name, xt}:
42      dir.insert(name, dir.sort(xt))
43
44# a name kept unless it is "." or ".."
45def dir.keep.pick(
46  dot: Bool,
47  +name: String,
48  rest: Unit -> List<&2, String>
49) -> List<&2, String>:
50  match dot:
51    case True{}:
52      rest(Unit{})
53    case False{}:
54      Con{name, rest(Unit{})}
55
56# the names that are not "." or "..", in their order
57def dir.keep(xs: List<&2, String>) -> List<&2, String>:
58  match xs:
59    case Nil{}:
60      Nil{}
61    case Con{+name, xt}:
62      dir.keep.pick(dir.dot(name), name, _u => dir.keep(xt))
63
64# what dir.list answers for the raw names a directory read gave
65def dir.names(raw: List<&2, String>) -> List<&2, String>:
66  dir.sort(dir.keep(raw))
67
68# what dir.list answers for a directory read's answer: its names, or the
69# failure unchanged
70def dir.step(
71  res: Result<&1, &1, U32 & String, List<&2, String>>
72) -> Result<&1, &1, U32 & String, List<&2, String>>:
73  match res:
74    case Fail{error}:
75      Fail{error}
76    case Done{raw}:
77      Done{dir.names(raw)}