Skip to content

Instantly share code, notes, and snippets.

@dball
Created July 12, 2016 18:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dball/d9f9bb7b6ea796e0de2ae49f6b21066e to your computer and use it in GitHub Desktop.
Save dball/d9f9bb7b6ea796e0de2ae49f6b21066e to your computer and use it in GitHub Desktop.
(defn charseq-in
[& options]
(let [{:keys [count min-count max-count chars]} options]
(s/coll-of (or chars char?)
:count count
:min-count min-count
:max-count max-count)))
(defn string-like
[spec-or-k]
(let [spec (#'s/specize spec-or-k)]
(reify s/Spec
(conform* [_ s]
(if (string? s)
(s/conform* spec (vec s))
::s/invalid))
(unform* [_ cs]
(string/join (s/unform* spec cs)))
(explain* [_ path via in x]
;; TODO possibly stringify the problems
(s/explain* spec path via in (vec x)))
(gen* [_ overrides path rmap]
(gen/fmap string/join (s/gen* spec overrides path rmap)))
(with-gen* [_ gfn]
(throw (Exception. "Not yet implemented")))
(describe* [_]
;; TODO ns qualify the string-like symbol?
(cons `string-like (s/describe* spec))))))
(defn string-in
[& options]
(string-like (apply charseq-in options)))
(s/def ::hostname-charseq
(let [chars (set (seq (str "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789")))]
(s/and
(charseq-in :chars (conj chars \-) :min-count 1 :max-count 64)
(s/cat :prefix (s/+ chars)
:sections (s/* (s/cat :hyphen (s/+ #{\-})
:suffix (s/+ chars)))))))
(s/def ::hostname
(string-like ::hostname-charseq))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment