Initial checkin

This commit is contained in:
Niten 2022-07-09 10:51:47 -07:00
commit 9d6ed7453d
8 changed files with 203 additions and 0 deletions

27
deps.edn Normal file
View File

@ -0,0 +1,27 @@
{
:paths ["src"]
:deps {
org.clojure/clojure { :mvn/version "1.11.1" }
org.clojure/core.async { :mvn/version "1.5.648" }
}
:aliases {
:test {
:extra-paths ["test"]
:extra-deps {
io.github.cognitect-labs/test-runner
{
:git/url "https://github.com/cognitect-labs/test-runner.git"
:sha "dfb30dd6605cb6c0efc275e1df1736f6e90d4d73"
}
}
:main-opts ["-m" "cognitect.test-runner"]
:exec-fn cognitect.test-runner.api/test
}
:lint {
:replace-deps { clj-kondo/clj-kondo {:mvn/version "2022.04.25"} }
:main-opts ["-m" "clj-kondo.main" "--lint" "src"]
}
}
}

View File

@ -0,0 +1,24 @@
(ns firmament.connection
(:require [clojure.edn :as edn])
(:import java.security.MessageDigest))
(defprotocol IFirmConnection
(read! [self id])
(write! [self data]))
(defn- sha256 [string]
(let [digest (.digest (MessageDigest/getInstance "SHA-256")
(.getBytes string "UTF-8"))]
(apply str (map (partial format "%02x") digest))))
(defn firmament-cache []
(let [store (atom {})]
(reify IFirmConnection
(read! [_ id]
(some-> (get @store id)
(edn/read-string)))
(write! [_ data]
(let [data-str (-> data prn-str)
id (sha256 data-str)]
(swap! store assoc id data-str)
id)))))

26
src/firmament/core.clj Normal file
View File

@ -0,0 +1,26 @@
(ns firmament.core
(:require [clojure.string :as str]))
;; Namespaces and code files
;; Dependencies specify namespaces, and the same rules as clojure apply
(defprotocol IFirmFilesystem
(read [self filename])
(write [self filename content])
(entries [self dirname]))
(defn make-filesystem
([conn] (make-filesystem [conn nil]))
([conn original-root]
(let [root (atom original-root)]
(reify IFirmFilesystem
(read [_ path]
(read-file conn @root path))
(write [_ path content]
(swap! root
(fn [old-root]
(write-path conn old-root path content))))
(entries [_ dirname]
(list-entries conn @root dirname))))))

View File

@ -0,0 +1,36 @@
(ns firmament.directory
(:require [firmament.directory :as dir]
[firmament.type :as t]
[clojure.spec.alpha :as s]))
(s/def ::entries (s/map-of keyword? ::t/firmament-id))
(defn create [& entries]
{::t/type ::t/directory
::entries (apply hash-map entries)})
(defn entry-id [dir entry]
(get-in dir [::entries entry]))
#_(defn- load-entry! [conn dir entry]
(conn/read! conn (get-entry-id dir entry)))
#_(defn- read-or-create! [conn id]
(if-let [dir (conn/read! conn id)]
dir
(create)))
#_(defn load! [conn dir entry]
(dir/read-or-create! conn (get-entry-id dir entry)))
#_(defn add-entry! [conn dir entry data]
(assoc-in dir [::entries entry] (conn/write conn data)))
(defn entries [dir]
(::entries dir))
(defn add-entry [dir entry id]
(assoc-in dir [::entries entry] id))
(defn directory? [o]
(and (map? o) (= ::t/directory (::t/type o))))

View File

@ -0,0 +1,21 @@
(ns firmament.filesystem
(:require [firmament.path :as path]))
(defprotocol IFirmFilesystem
(read! [self filename])
(write! [self filename content])
(entries! [self dirname]))
(defn make-filesystem
([conn] (make-filesystem conn nil))
([conn original-root]
(let [root (atom original-root)]
(reify IFirmFilesystem
(read! [_ path]
(path/read-file! conn @root path))
(write! [_ path content]
(swap! root
(fn [old-root]
(path/write! conn old-root path content))))
(entries! [_ dirname]
(path/list-entries! conn @root dirname))))))

8
src/firmament/object.clj Normal file
View File

@ -0,0 +1,8 @@
(ns firmament.object
(:require [firmament.type :as t]))
(defn create [data]
{::t/type ::t/object ::t/data data})
(defn data [obj]
(::t/data obj))

49
src/firmament/path.clj Normal file
View File

@ -0,0 +1,49 @@
(ns firmament.path
(:require [clojure.string :as str]
[firmament.directory :as dir]
[firmament.object :as object]
[firmament.connection :as conn]))
(defn- path-elements [path]
(str/split path #"/"))
(defn- read! [conn root path]
(loop [curr (conn/read! conn root)
remaining (path-elements path)]
(when (nil? curr)
(throw (ex-info (str "path does not exist: " path)
{:root root})))
(if (not (seq remaining))
curr
(recur (conn/read! conn (dir/entry-id curr (first remaining)))
(rest remaining)))))
(defn read-file! [conn root path]
(some-> (read! conn root path) (object/data)))
(defn list-entries! [conn root path]
(some-> (read! conn root path) (dir/entries) (keys)))
(defn save-entry! [conn dir entry data]
(dir/add-entry dir entry (conn/write! conn data)))
(defn load-dir-entry! [conn base entry]
(if-let [dir (conn/read! conn (dir/entry-id base entry))]
dir
(dir/create)))
(defn- write-internal [conn curr [el & els] obj]
(if (seq els)
(save-entry! conn curr el
(write-internal conn
(load-dir-entry! conn curr el)
els
obj))
(save-entry! conn curr el obj)))
(defn write! [conn root path data]
(conn/write! conn
(write-internal conn
(conn/read! conn root)
(path-elements path)
(object/create data))))

12
src/firmament/type.clj Normal file
View File

@ -0,0 +1,12 @@
(ns firmament.type
(:require [clojure.spec.alpha :as s]))
(def firmament-id? string?)
(s/def ::firmament-id firmament-id?)
(def firmament-data? string?)
(s/def ::type #{::directory ::object})
(s/def ::data firmament-data?)