aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/world/file.lux
blob: 1c968b888f08affc90340113742c60f7e5c0cb58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
(;module:
  lux
  (lux (control [monad #+ do]
                ["ex" exception #+ exception:])
       (concurrency ["P" promise]
                    ["T" task])
       (data ["E" error]
             (coll [array]))
       (time ["i" instant]
             ["d" duration])
       (world [blob #+ Blob])
       [io]
       [host]))

(exception: Could-Not-Read-All-Data)

(type: #export File Text)

(host;import #long java.io.File
  (new [String])
  (exists [] #io #try boolean)
  (mkdir [] #io #try boolean)
  (delete [] #io #try boolean)
  (length [] #io #try long)
  (listFiles [] #io #try (Array java.io.File))
  (getAbsolutePath [] #io #try String)
  (renameTo [java.io.File] #io #try boolean)
  (isFile [] #io #try boolean)
  (isDirectory [] #io #try boolean)
  (lastModified [] #io #try long)
  (setLastModified [long] #io #try boolean)
  (canRead [] #io #try boolean)
  (canWrite [] #io #try boolean)
  (canExecute [] #io #try boolean))

(host;import java.lang.AutoCloseable
  (close [] #io #try void))

(host;import java.io.OutputStream
  (write [(Array byte)] #io #try void)
  (flush [] #io #try void))

(host;import java.io.FileOutputStream
  (new [java.io.File boolean] #io #try))

(host;import java.io.InputStream
  (read [(Array byte)] #io #try int))

(host;import java.io.FileInputStream
  (new [java.io.File] #io #try))

(do-template [<name> <flag>]
  [(def: #export (<name> data file)
     (-> Blob File (T;Task Unit))
     (P;future (do (E;ErrorT io;Monad<IO>)
                 [stream (FileOutputStream.new [(java.io.File.new file) <flag>])
                  _ (OutputStream.write [data] stream)
                  _ (OutputStream.flush [] stream)]
                 (AutoCloseable.close [] stream))))]

  [append true]
  [write  false]
  )

(def: #export (read file)
  (-> File (T;Task Blob))
  (P;future (do (E;ErrorT io;Monad<IO>)
              [#let [file' (java.io.File.new file)]
               size (java.io.File.length [] file')
               #let [data (blob;create (int-to-nat size))]
               stream (FileInputStream.new [file'])
               bytes-read (InputStream.read [data] stream)
               _ (AutoCloseable.close [] stream)]
              (if (i.= size bytes-read)
                (wrap data)
                (io;io (ex;throw Could-Not-Read-All-Data file))))))

(def: #export (size file)
  (-> File (T;Task Nat))
  (P;future (do (E;ErrorT io;Monad<IO>)
              [size (java.io.File.length [] (java.io.File.new file))]
              (wrap (int-to-nat size)))))

(def: #export (files dir)
  (-> File (T;Task (List File)))
  (P;future (do (E;ErrorT io;Monad<IO>)
              [files (java.io.File.listFiles [] (java.io.File.new dir))]
              (monad;map @ (java.io.File.getAbsolutePath [])
                         (array;to-list files)))))

(do-template [<name> <method>]
  [(def: #export (<name> file)
     (-> File (T;Task Bool))
     (P;future (<method> [] (java.io.File.new file))))]

  [exists?      java.io.File.exists]
  [make-dir     java.io.File.mkdir]
  [delete       java.io.File.delete]
  [file?        java.io.File.isFile]
  [directory?   java.io.File.isDirectory]
  [can-read?    java.io.File.canRead]
  [can-write?   java.io.File.canWrite]
  [can-execute? java.io.File.canExecute]
  )

(def: #export (move target source)
  (-> File File (T;Task Bool))
  (P;future (java.io.File.renameTo [(java.io.File.new target)]
                                   (java.io.File.new source))))

(def: #export (get-last-modified file)
  (-> File (T;Task i;Instant))
  (P;future (do (E;ErrorT io;Monad<IO>)
              [millis (java.io.File.lastModified [] (java.io.File.new file))]
              (wrap (|> millis d;from-millis i;absolute)))))

(def: #export (set-last-modified time file)
  (-> i;Instant File (T;Task Bool))
  (P;future (java.io.File.setLastModified [(|> time i;relative d;to-millis)]
                                          (java.io.File.new file))))