Skip to content

Instantly share code, notes, and snippets.

@dball
Created July 12, 2016 18:50
Show Gist options
  • Select an option

  • Save dball/d9f9bb7b6ea796e0de2ae49f6b21066e to your computer and use it in GitHub Desktop.

Select an option

Save dball/d9f9bb7b6ea796e0de2ae49f6b21066e to your computer and use it in GitHub Desktop.

Revisions

  1. dball created this gist Jul 12, 2016.
    45 changes: 45 additions & 0 deletions string.clj
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,45 @@
    (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))