/
filemap.clj
84 lines (73 loc) · 2.39 KB
/
filemap.clj
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
(ns clojupyter.install.filemap
(:require [clojupyter.util-actions :as u!]
[clojure.java.io :as io]
[clojure.pprint :as pp]
[io.simplect.compose :refer [p P]]))
(use 'clojure.pprint)
(declare filemap filemap?)
(defn- fstype
[v]
(when (instance? java.io.File v)
(let [v ^java.io.File v]
(cond
(not (.exists v)) nil
(.isFile v) :filetype/file
(.isDirectory v) :filetype/directory
:else :filetype/other))))
(defprotocol filemap-proto
(dir [_ nm])
(entity [_ nm])
(exists [_ nm] [_ nm default])
(file [_ nm])
(get-map [_])
(names [_]))
(deftype FileMap [_m]
filemap-proto
(dir [fm nm] (when-let [typ (exists fm nm)]
(when (= typ :filetype/directory)
nm)))
(entity [fm nm] (when (exists fm nm)
nm))
(exists [fm nm] (exists fm nm nil))
(exists [_ nm default] (clojure.core/get _m nm default))
(file [fm nm] (when-let [typ (exists fm nm)]
(when (= typ :filetype/file)
nm)))
(get-map [_] _m)
(names [_] (keys _m))
Object
(toString [_] (str "#filemap" (with-out-str (print _m)) ""))
(equals [fm v] (boolean
(when (filemap? v)
(= _m (get-map v))))))
(alter-meta! #'->FileMap (P assoc :private true))
(defmethod print-method FileMap
[^FileMap fm ^java.io.Writer w]
(if pp/*print-pretty*
(binding [*out* (pp/get-pretty-writer w)
pp/*print-suppress-namespaces* true]
(pp/pprint-logical-block
(.write w "#filemap")
(pp/pprint-logical-block (pp/write (get-map fm)))))
(.write w (str fm))))
(def filemap? (p instance? FileMap))
(defn- coerce-to-map
[v]
(cond
(instance? java.io.File v) {v (fstype v)}
(nil? v) {}
(map? v) v
(filemap? v) (get-map v)
(string? v) (recur (io/file v))
(seq? v) (recur (apply filemap v))
(vector? v) (recur (apply filemap v))
(set? v) (recur (apply filemap v))
:else (u!/throw-info (str "Can't be coerced to map: " v) {:fm v})))
(defn filemap
([] (->FileMap {}))
([fm]
(->FileMap (coerce-to-map fm)))
([fm1 fm2]
(filemap (merge (coerce-to-map fm1) (coerce-to-map fm2))))
([fm1 fm2 & fms]
(apply filemap (filemap fm1 fm2) fms)))