Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mpenet/spex
Utils/Helpers for clojure spec
https://github.com/mpenet/spex
Last synced: 23 days ago
JSON representation
Utils/Helpers for clojure spec
- Host: GitHub
- URL: https://github.com/mpenet/spex
- Owner: mpenet
- Created: 2016-07-27T10:58:23.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2019-11-21T15:03:03.000Z (almost 5 years ago)
- Last Synced: 2024-05-01T23:59:16.489Z (7 months ago)
- Language: Clojure
- Size: 65.4 KB
- Stars: 16
- Watchers: 3
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# spex
[![cljdoc badge](https://cljdoc.xyz/badge/cc.qbits/spex)](https://cljdoc.xyz/d/cc.qbits/spex/CURRENT)Small utility/extension library for `clojure.spec`.
Subject to changes/breakage. Use at own risk.
At the moment it does only 3 things:
assuming
``` clojure
(require '[qbits.spex :as spex])
```
* add `def-derived` which creates a keyword hierarchy behind the
scenes (the hierarchy is internal/scoped to spex/ so no risk of
cluttering the global one)```clj
(s/def ::foo string?)
(spex/def-derived ::bar ::foo)
```
equivalent to:
```clj
(s/def ::foo string?)
(s/def ::bar ::foo)
(spex/derive ::bar ::foo)
```but that also works with maps, here foo will derive from ::baz and ::bar
```clj
(spex/def-merged ::foo [::bar ::baz])
```
equivalent to:
```clj
(s/def ::foo (s/merge ::bar ::baz))
(spex/derive ::foo ::bar)
(spex/derive ::foo ::baz)
```So why do that? well you can then inspect the hierarchy, which can
be handy:``` clj
(s/def-merged ::foo [::bar ::baz])(spex/ancestors ::foo) => #{::bar ::baz}
(spex/isa? ::foo ::bar) => true
(spex/isa? ::foo ::baz) => true
```* adds a metadata registry for registered specs, it currently supports
variants of `vary-meta!`, `with-meta!`, `meta`, adds
`unregister-meta!` and `with-doc`.you can then write code like:
```clj
(-> (s/def ::foo string?)
(spex/vary-meta! assoc :something :you-need));; and retrieve the values with spex/meta
(spex/meta ::foo) => {:something :you-need}
```Since we have this hierarchy in place we can integrate this into
metadata retrieval. Told you it could be useful :)```clj
(spex/def-derived ::bar ::foo)(spex/meta ::bar) => nil
;; remember we have meta data on :foo already, such that:
(spex/meta ::foo) => {:something :you-need};; register meta at ::bar level
(spex/vary-meta! ::bar assoc :another :key);; just the meta of ::bar
(spex/meta ::bar) => {:another :key};; retrieve the meta for ::bar but also all its ancestors if you pass true to spex/meta
(spex/meta ::bar true) => {:something :you-need, :another :key}
```and `spex/with-doc` is just sugar on top of all this to add docstrings to specs
```clj
(spex/with-doc ::foo "bla bla bla")(s/doc ::foo) => "bla bla bla"
```All the functions that mutate the metadata of a spec return the spec
key, that makes chaining easier, same goes for `spex/def-derived`:```clojure
(-> (s/def ::foo string?)
(spex/vary-meta! assoc :something :you-need)
(cond->
something?
(spex/vary-meta! assoc :something-else :you-might-need)))
```
The internal hierarchy is queriable just like the global keyword hierarchy,
you can use `spex/isa?` `spex/descendants` `spex/ancestors`
`spex/parents` `spex/derive` `spex/underive`, which are just
partially applied functions over the same functions in core with our
own internal hierarchy `spex/spec-hierarchy`.```clojure
(s/def ::port (int-in-range? 1 65535))
(spex/def-derived ::redis-port ::port)(spex/isa? ::redis-port ::port) => true
(spex/def-derived ::cassandra-port ::port)
;; list all things ::port
(spex/descendants ::port) => #{::redis-port ::cassandra-port}))```
This only works for aliases obviously.
* adds a sugar to create namespaces within a ns. Ex: if you are in
the user namespace `(spex/rel-ns 'foo.bar)` would create
user.foo.bar## Installation
spex is [available on Clojars](https://clojars.org/cc.qbits/spex).
[![Clojars Project](https://img.shields.io/clojars/v/cc.qbits/spex.svg)](https://clojars.org/cc.qbits/spex)
## License
Copyright © 2016 [Max Penet](http://twitter.com/mpenet)
Distributed under the
[Eclipse Public License](http://www.eclipse.org/legal/epl-v10.html),
the same as Clojure.