~subsetpark/bagatto

73d12c5d81e7f1aeac69cea57483a8bce6b9b4be — Zach Smith 10 months ago e1f4d76
Add 0-arity data loader option
1 files changed, 33 insertions(+), 9 deletions(-)

M main.janet
M main.janet => main.janet +33 -9
@@ 4,24 4,24 @@


(def bagatto
  ``
  ```
  An environment populated by the "stdlib" we want to expose to
  template and index module authors.
  ``
  ```
  (require "bagatto-require"))

# Monkey-patch the temple environment with our additional functions.
(merge-into temple/base-env bagatto)

(defn load-file [index]
  ``
  ```
  Given the filename of our index module, evaluate it in the execution
  environment with our "stdlib" in it. This will give index module
  authors access to its additional namespaces without having to import
  them (and, as the environment was created at compile time, without
  those libraries having to be present when the index module is
  written).
  ``
  ```
  (temple/add-loader)
  (dofile index :env bagatto))



@@ 42,23 42,47 @@
(defn- set-defaults [spec defaults] (table/setproto (struct->table spec) (struct->table defaults)))

(defn load-data [data-spec defaults]
  ``
  ```
  First phase of main business logic. `data-spec` contains a
  specification of all the sources necessary to generate our `attrs`
  entries, which are the data structures to be used in generating the
  site.
  ``

  A data specification can be in one of four formats:
  
  1. A simple struct with only an :attrs field. The attrs generated
  will simply be the value at `:attrs`.
  2. A struct with a :src that's a string path to a file relative from
  the current directory, and an :attrs function that will be called on
  the contents of the file.
  3. A struct with a :src that's a 0-arity function that will return a
  [filename file-contents] tuple, and an :attrs function that will be
  called on the file-contents.
  4. A struct with a :src that returns a fiber which will yield some
  finite number of [filename file-contents] tuples, and an :attrs
  function that will be called on each file-contents.
  ```
  (defn- make-attrs [filename file-contents attrs-f]
    (->> @{:path filename :src file-contents}
         (attrs-f file-contents)))
  
  (let [res @{}]
    (loop [[entry spec] :pairs data-spec]
      (let [with-defaults (set-defaults spec defaults)]
        (put res entry (match with-defaults
                         
                         ({:src loader :attrs attrs-f} (fiber? loader))
                         (seq [[filename file-contents] :generate loader]
                              (->> @{:path filename :src file-contents}
                                   (attrs-f file-contents)))
                              (make-attrs filename file-contents attrs-f))
                         
                         ({:src loader :attrs attrs-f} (function? loader))
                         (let [[filename file-contents] (loader)]
                           (make-attrs filename file-contents attrs-f))
                         
                         ({:src path :attrs attrs-f} (string? path))
                         (let [file-contents (slurp path)]
                           (->> @{:path path :src file-contents} (attrs-f file-contents)))
                           (make-attrs path file-contents attrs-f))
                         
                         {:attrs attrs}
                         attrs))))
    res))