src/file.bend
snap@1.4.0.0 · 105 lines · 13 definitions
1
2import Base
3
4
5def file.slurp.end(file: File, acc: String) -> IO(String):
6 do IO<String>:
7 File.close(file)
8 return acc
9
10
11def file.slurp.cut(chunk: String, file: File, acc: String, rest: File -> String -> IO(String)) -> IO(String):
12 match chunk:
13 case SNil{}:
14 file.slurp.end(file, acc)
15 case SCon{c, t}:
16 rest(file, acc ++ SCon{c, t})
17
18
19def file.slurp.more(
20 res: Result<&1, &1, U32 & String, String>,
21 file: File,
22 acc: String,
23 rest: File -> String -> IO(String)
24) -> IO(String):
25 match res:
26 case Fail{_e}:
27 file.slurp.end(file, acc)
28 case Done{chunk}:
29 file.slurp.cut(chunk, file, acc, rest)
30
31
32def file.slurp.next(
33 got: File & Result<&1, &1, U32 & String, String>,
34 acc: String,
35 rest: File -> String -> IO(String)
36) -> IO(String):
37 (file, res) = got
38 file.slurp.more(res, file, acc, rest)
39
40
41def file.slurp(fuel: Nat, file: File, acc: String) -> IO(String):
42 match fuel:
43 case 0n:
44 file.slurp.end(file, acc)
45 case 1n+f:
46 do IO<String>:
47 got : File & Result<&1, &1, U32 & String, String> <- File.read(file, 65536)
48 file.slurp.next(got, acc, fl => a => file.slurp(f, fl, a))
49
50
51
52
53def file.unsized() -> Nat:
54 U32.to_nat(100000)
55
56
57def file.reads.given(none: Bool, bytes: U32) -> Nat:
58 match none:
59 case True{}:
60 file.unsized()
61 case False{}:
62 U32.to_nat(U32.add(U32.div(bytes, 65536), 2))
63
64
65
66def file.reads(+bytes: U32) -> Nat:
67 file.reads.given(U32.is_zero(bytes), bytes)
68
69
70def file.reads.of(res: Result<&1, &1, U32 & String, U32>) -> Nat:
71 match res:
72 case Fail{_e}:
73 file.unsized()
74 case Done{bytes}:
75 file.reads(bytes)
76
77
78def file.read.sized(got: File & Result<&1, &1, U32 & String, U32>) -> IO(String):
79 (file, res) = got
80 file.slurp(file.reads.of(res), file, "")
81
82
83def file.read.opened(res: Result<&1, &1, U32 & String, File>) -> IO(Maybe<&2, String>):
84 match res:
85 case Fail{_e}:
86 IO.pure(Maybe<&2, String>, None{})
87 case Done{file}:
88 do IO<Maybe<&2, String>>:
89 got : File & Result<&1, &1, U32 & String, U32> <- File.size(file)
90 text : String <- file.read.sized(got)
91 return Some{text}
92
93
94def file.read(path: String) -> IO(Maybe<&2, String>):
95 do IO<Maybe<&2, String>>:
96 res : Result<&1, &1, U32 & String, File> <- File.open(path, "r")
97 file.read.opened(res)
98
99
100def file.text_of(got: Maybe<&2, String>) -> String:
101 match got:
102 case None{}:
103 ""
104 case Some{s}:
105 s