fs/write.bend
cswap-bend-cli@0.1.0.0 · 94 lines · 17 definitions
1import Base
2import cswap-bend-cli@0.1.0.0/fs.bend as Fs
3
4
5
6def create.done(r: Fs.Res(File)) -> IO(Fs.Res(Unit)):
7 match r:
8 case Fail{e}:
9 IO.pure(Fs.Res(Unit), Fail{e})
10 case Done{f}:
11 IO.bind(Unit, Fs.Res(Unit), File.close(f), u => IO.pure(Fs.Res(Unit), Done{Unit{}}))
12
13
14def create(path: String) -> IO(Fs.Res(Unit)):
15 IO.bind(Fs.Res(File), Fs.Res(Unit), File.open(path, "a"), create.done)
16
17def put.close(fr: File & Fs.Res(Unit)) -> IO(Fs.Res(Unit)):
18 (f, r) = fr
19 IO.bind(Unit, Fs.Res(Unit), File.close(f), u => IO.pure(Fs.Res(Unit), r))
20
21def put.write(data: String, r: Fs.Res(File)) -> IO(Fs.Res(Unit)):
22 match r:
23 case Fail{e}:
24 IO.pure(Fs.Res(Unit), Fail{e})
25 case Done{f}:
26 IO.bind(File & Fs.Res(Unit), Fs.Res(Unit), File.write(f, data), put.close)
27
28
29def put(path: String, data: String) -> IO(Fs.Res(Unit)):
30 IO.bind(Fs.Res(File), Fs.Res(Unit), File.open(path, "w"), r => put.write(data, r))
31
32def chmod(mode: String, path: String) -> IO(Fs.Res(Unit)):
33 Fs.tool_unit("/bin/chmod", ["--", mode, path])
34
35def rename(src: String, dst: String) -> IO(Fs.Res(Unit)):
36 Fs.tool_unit("/bin/mv", ["-f", "--", src, dst])
37
38
39def remove(path: String) -> IO(Fs.Res(Unit)):
40 Fs.tool_unit("/bin/rm", ["-f", "--", path])
41
42def mkdir_p(path: String) -> IO(Fs.Res(Unit)):
43 Fs.tool_unit("/bin/mkdir", ["-p", "--", path])
44
45def publish.fail(r: Fs.Res(Unit), +tmp: String) -> IO(Fs.Res(Unit)):
46 match r:
47 case Done{u}:
48 IO.pure(Fs.Res(Unit), Done{u})
49 case Fail{e}:
50 IO.bind(Fs.Res(Unit), Fs.Res(Unit), remove(tmp), c => IO.pure(Fs.Res(Unit), Fail{e}))
51
52def publish.mv(r: Fs.Res(Unit), +tmp: String, +path: String) -> IO(Fs.Res(Unit)):
53 match r:
54 case Fail{e}:
55 publish.fail(Fail{e}, tmp)
56 case Done{u}:
57 IO.bind(Fs.Res(Unit), Fs.Res(Unit), rename(tmp, path), m => publish.fail(m, tmp))
58
59def publish.put(r: Fs.Res(Unit), +tmp: String, +path: String, +data: String) -> IO(Fs.Res(Unit)):
60 match r:
61 case Fail{e}:
62 publish.fail(Fail{e}, tmp)
63 case Done{u}:
64 IO.bind(Fs.Res(Unit), Fs.Res(Unit), put(tmp, data), w => publish.mv(w, tmp, path))
65
66def publish.chmod(r: Fs.Res(Unit), +tmp: String, +path: String, +data: String, +mode: String) -> IO(Fs.Res(Unit)):
67 match r:
68 case Fail{e}:
69 publish.fail(Fail{e}, tmp)
70 case Done{u}:
71 IO.bind(Fs.Res(Unit), Fs.Res(Unit), chmod(mode, tmp), c => publish.put(c, tmp, path, data))
72
73def publish.create(+tmp: String, +path: String, +data: String, +mode: String) -> IO(Fs.Res(Unit)):
74 IO.bind(Fs.Res(Unit), Fs.Res(Unit), create(tmp), c => publish.chmod(c, tmp, path, data, mode))
75
76def publish.tmp(r: Fs.Res(U32), +path: String, +data: String, +mode: String) -> IO(Fs.Res(Unit)):
77 match r:
78 case Fail{e}:
79 IO.pure(Fs.Res(Unit), Fail{e})
80 case Done{n}:
81 publish.create(path ++ ".tmp-" ++ U32.show(n), path, data, mode)
82
83
84
85
86
87def write_atomic(path: String, data: String, mode: String) -> IO(Fs.Res(Unit)):
88 IO.bind(Fs.Res(U32), Fs.Res(Unit), IO.random_u32(), r => publish.tmp(r, path, data, mode))
89
90
91
92
93def append(path: String, data: String) -> IO(Fs.Res(Unit)):
94 IO.bind(Fs.Res(File), Fs.Res(Unit), File.open(path, "a"), r => put.write(data, r))