This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-11-19
Channels
- # announcements (3)
- # asami (3)
- # babashka (39)
- # beginners (65)
- # calva (13)
- # cider (4)
- # clj-kondo (69)
- # cljdoc (19)
- # cljs-dev (2)
- # clojure (90)
- # clojure-dev (10)
- # clojure-europe (61)
- # clojure-france (15)
- # clojure-nl (8)
- # clojure-uk (2)
- # clojurescript (28)
- # conjure (2)
- # core-logic (4)
- # cursive (8)
- # datalevin (5)
- # datascript (7)
- # datomic (14)
- # depstar (4)
- # events (1)
- # graphql (7)
- # holy-lambda (5)
- # jobs (5)
- # kaocha (1)
- # malli (14)
- # membrane-term (13)
- # missionary (13)
- # nextjournal (6)
- # off-topic (1)
- # polylith (15)
- # portal (10)
- # re-frame (35)
- # reitit (1)
- # remote-jobs (3)
- # schema (3)
- # sci (121)
- # spacemacs (6)
- # tools-build (8)
- # tools-deps (74)
- # xtdb (7)
How would we write a schema for a string made of two components a
and b
separated by a /
where the schema of b
depends on the value of a
. The valid values of a
are known in advance.
For instance:
1. When a
is "ip"
, b
should be a valid ip
2. When a
is "domain"
, b
should be a valid domain
Here are a few examples of valid and invalid data:
• ip/127.0.0.1
is valid
• ip/111
is not valid
• domain/cnn.com
is valid
• domain/aa
is not valid
• kika/aaa
is not valid
Add a decoder which splits the string at the separator. Then it's a multi schema for a tuple which dispatches of first
You mean a custom transformer like in https://github.com/metosin/malli/blob/master/docs/tips.md#trimming-strings ?
(require '[malli.transform :as mt])
(require '[malli.core :as m])
(require '[clojure.string :as str])
;; a decoding transformer, only mounting to :string schemas with truthy :string/trim property
(defn string-trimmer []
(mt/transformer
{:decoders
{:string
{:compile (fn [schema _]
(let [{:string/keys [trim]} (m/properties schema)]
(when trim #(cond-> % (string? %) str/trim))))}}}))
;; trim me please
(m/decode [:string {:string/trim true, :min 1}] " kikka " string-trimmer)
; => "kikka"
But then, it's the responsibility of the validate
callers to explicitly mention my custom transformer. Is there a way to have the custom transformer somehow embedded in the schema?
You can do some sort of schema constructor, too:
(def Composite (-simple-schema (fn [A B] [:tuple {:decode/string #(str/split % #"/") A B])))
Thanks @UK0810AQ2 I'll give it a try
The way I found works well for me is starting from an ideal representation then working backwards with transformers to get there
It would be nice to be able to have a distinct error message when we explain why the data is invalid. The explanation could be either:
1. Unknown value of a
2. b
is not a valid ip
3. b
is not a valid domain
I don't know how malli works, but if you can use regexes to match strings you could write something like:
((ip)/(:ip-address:)|(domain)/(:domain-name:))