~subsetpark/bagatto

bagatto/src/loaders.janet -rw-r--r-- 2.5 KiB
4fc04b3a — Zach Smith Add render some 2 months ago
                                                                                
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
(import /src/error)
(import /src/threads)
(import /src/env)

(defn- set-cxt! [spec-name]
  (setdyn :error-context {:spec-name spec-name}))

(defn- make-attrs [parser filename &opt file-contents]
  (let [base-attrs @{:path filename :contents file-contents}]
    (try (parser file-contents base-attrs)
      ([err fib] (propagate (error/attrs-error err parser) fib)))))

(defn- from-file-spec-loader
  ```
  A loader that takes either a single file spec or a sequence of file
  specs and sends back a list of attributes.
  ```
  [spec-name loader parser transform-f]
  (fn [parent]
    (set-cxt! spec-name)
    (threads/print "Loading " spec-name "...")

    (let [loader-specs (try (loader)
                         ([err fib] (propagate (error/loader-spec-error spec-name loader) fib)))
          res (match loader-specs
                {:each ind}
                (do
                  (threads/print "[" spec-name "] Loading " (length ind) " files")
                  (-> (seq [spec :in ind]
                        (if (indexed? spec)
                          (make-attrs parser ;spec)
                          (make-attrs parser spec)))
                      (transform-f)))

                {:some spec}
                (make-attrs parser ;spec)

                _ (error/loader-spec-error spec-name loader))]
      (:send parent [:res spec-name res]))))

(defn- from-path-loader
  ```
  A loader that takes a literal file path and generates file
  attributes.
  ```
  [spec-name path parser]
  (fn [parent]
    (set-cxt! spec-name)
    (threads/print "Loading " spec-name " (" path ")...")

    (let [file-contents (slurp path)
          res (make-attrs parser path file-contents)]
      (:send parent [:res spec-name res]))))

(defn- bare-attr-loader
  ```
  A loader that takes an attributes literal and returns it.
  ```
  [spec-name attrs]
  (set-cxt! spec-name)

  (fn [parent]
    (threads/print "Loaded " spec-name)
    (:send parent [:res spec-name attrs])))

(defn from-spec
  [spec spec-name]
  (let [transform-f (or (spec :transform) identity)]
    (match spec
      ({:src loader :attrs parser} (function? loader))
      (from-file-spec-loader spec-name
                             loader
                             parser
                             transform-f)

      ({:src path :attrs parser} (string? path))
      (from-path-loader spec-name
                        path
                        parser)

      {:attrs attrs}
      (bare-attr-loader spec-name
                        attrs)

      _ (error/data-error spec))))