Fork me on GitHub
#malli
<
2022-01-20
>
Abhinav04:01:48

how do I express this in a schema?

{"hi" {:greeting "hi" :id 1} "hello" {:greeting "hello" :id 2} "hiee" {:greeting "hiee" :id 3}}
I have a function that transforms a map like this
[{:greeting "hi" :id 1}{:greeting "hello" :id 2}{:greeting "hiee" :id 3}]
into the one above, the values of :greeting aren’t known before hand

ikitommi11:01:20

maybe: [:map-of :string [:map [:id :int] [:greeting :string]]]

Abhinav11:01:36

That is a good suggestion, but I want to say that the key of the map has to the be equal to the value of the :greeting key. so [:map-of :string [:map [:id :int] [:greeting :string]]] would be valid for {"foostring" {:greeting "hi" :id 3}} but the above won’t be valid

Abhinav11:01:10

I don’t know if what I’m tryign to do is an anti-pattern:sweat_smile:

ikitommi11:01:28

no, it’s all valid, maybe:

(def Schema
  (m/schema
   [:and
    [:map-of :string [:map [:id :int] [:greeting :string]]]
    [:fn (partial every? (fn [[k d]] (= k (:greeting d))))]]))

(m/validate
 Schema
 {"hi" {:greeting "hi" :id 1}
  "hello" {:greeting "hello" :id 2}
  "hiee" {:greeting "hiee" :id 3}})
; => true

(m/validate
 Schema
 {"hi" {:greeting "<<invalid>>" :id 1}
  "hello" {:greeting "hello" :id 2}
  "hiee" {:greeting "hiee" :id 3}})
; => false

clojure-spin 1
ikitommi11:01:50

m/explain here doesn’t produce correct place of error, could should do it, we could tune either :fn to support returning custom explain-results, or add support for generic :explain key for keys, or something. Someone should write an issue out of this.

Abhinav03:01:31

@U055NJ5CC thank you for your help. that was exactly what I was looking for.

rovanion12:01:23

I believe I'm just being daft here but I haven't been able to figure this out for more than an hour so: How do I resolve a keyword to a schema in the registry?

(def registry
  (atom {}))

(defn register! [type ?schema]
  (swap! registry assoc type ?schema))

;; Combine the default registry with our own mutable registry.
(mreg/set-default-registry!
 (mreg/composite-registry
    (mreg/fast-registry (malli/default-schemas))
    (mreg/mutable-registry registry)))

(register! :db/kasse
   [:map
    [:id                            [:int {:primary-key true :db-generated true}]]
    [:odlingsplats                  [:string {:foreign-key "odlingsplatser"}]]
    [:diameter_m                    :int]
    [:djup_m                        :int]
    [:volym_m2                      [:int {:db-generated true}]]])

(malli/walk
 :db/kasse
 (malli/schema-walker identity))
;; => :db/kasse
I've tried wrapping :db/kasse in different functions from malli but none seem to do the lookup. The lookup function in the core namespace is private. Just running (:db/kasse malli/default-registry) does not work either. (malli/schema :db/kasse) seems like the obvious choice but it seemingly has no effect.
(malli/walk
 (malli/schema :db/kasse)
 (malli/schema-walker identity))
;; => :db/kasse

ikitommi12:01:56

the :db/kasse returned is a Malli Schema instance, it’s print output is just the form, so looks like keyword. It’s type is :malli.core/schema, which is the internal eager reference, like a Var in Clojure. If you want to get the schema behind it, you can m/deref it. But, calling m/validate on :db/kasse works too. the :malli.core/schema forwards the calls to the actual instance, like Var. Hope this helps.

ikitommi12:01:33

also, walking it just work, try something like (m/ast :db/kasse) to verify

👀 1
rovanion13:01:10

Thank you, dereffing worked perfectly. Though I'm not sure I understand the latter reply:

(let [schema (malli/schema :db/kasse)]                                                                                
  (prn (type schema))                                                                                                 
  (malli/walk                                                                                                         
   schema                                                                                                             
   (malli/schema-walker identity))) 
;; => :db/kasse
;; printed: :malli.core/schema

mafcocinco16:01:17

hi all! Just started using malli and I have what I think is a pretty newbie question: Is there a way, in the context of a :map schema declaration to have mutually exclusive keys? That is “map should contain :a and :b together or :c by itself”.

Ben Sless17:01:53

Not atm, but it's an often requested feature

👍 1
jeroenvandijk18:01:15

Hi, I’ve been playing with the idea of using Malli as a way to define the main data model of an application. Many features are already in Malli I believe. One thing that might be missing is an easy way to generate consistent test and seed data. Maybe something like composite types are an useful addition?

(register! :user/first-name [:enum "john" "joe" "alex"])
(register! :user/last-name [:enum "smith" "wood" "lee"])

(register! :user/full-name
           [:composite {:schema string?
                        :compose (fn [first-name last-name]
                                   (str first-name " " last-name))
                        :fields [:user/first-name :user/last-name]}])

(register-entity! ::user
                  [:user/first-name
                   :user/last-name
                   :user/full-name])

(generate ::user)
;; => #:user{:first-name "joe", :last-name "wood", :full-name "joe wood"}
More here https://gist.github.com/jeroenvandijk/5e0785f25f7fdfeac7bc7a0be72cb62a#file-malli_composite_test-clj

👀 1
Ben Sless19:01:47

Did you just implement unification?

jeroenvandijk19:01:06

Not consciously 😅 Maybe accidentally? I was just thinking how do I get meaningful seed and test data when I’m just defining my attributes and entities

jeroenvandijk20:01:43

@UK0810AQ2 I see you did some work on unification yourself (https://github.com/metosin/malli/issues/474 and https://github.com/bsless/malli-keys-relations). My approach is not that advanced (or complete)

Ben Sless20:01:49

It's okay, my approach sucked anyway I'm becoming convinced the only solution is embedding micro kanren and I'm scared

jeroenvandijk20:01:10

Haha I can imagine