1616 [malli.util :as mu]
1717 [malli.transform :as mt]
1818 [malli.provider :as mp]
19+ [malli.generator :as mg]
1920 [malli.error :as me]
2021 [clojure.edn :as edn]
2122 [jsonista.core :as json]
@@ -653,6 +654,14 @@ only-in-encoded
653654; ; confusing they are, so if you can avoid the non trivial use cases,
654655; ; please do.
655656
657+ ; ; # Generators
658+
659+ ; ; We can generate data based on our schema
660+
661+ (mg/generate BinanceUserEvent3 {:registry registry})
662+
663+ ; ; # Providers
664+
656665; ; # Custom Schemas
657666
658667; ; ## Case study - URL schema
@@ -704,20 +713,20 @@ only-in-encoded
704713; ; CharacterAlignment
705714; ; ```
706715
707- ; ; - Why?
716+ ; ; #### Why?
708717; ; - Domain Modeling
709718; ; - What do schemas *mean*?
710719; ; - They model our domain with types and predicates
711720; ; - Similar to a type system
712721; ; - Types reflect the domain entities and data
713722; ; - We don't have `IntegerInRange100` entity or property
714- ; ; - Reuse
723+ ; ; #### Reuse
715724; ; - `MySchema` can be used in more than one place.
716725; ; - By naming the domain entity we make it possible to be reused correctly
717726; ; - One change propagates across the code base.
718727; ; - No need to change every occurrence of `:campaign-id`
719728
720- ; ; How?
729+ ; ; #### How?
721730
722731(def CampaignID [:int {:max 100 :min 0 }])
723732(def Message [:map [:campaign-id CampaignID]])
@@ -729,19 +738,19 @@ only-in-encoded
729738(def Foo IntRange0To100 )
730739(def Message [:map [:campaign-id CampaignID] [:foo Foo]])
731740
732- ; ; - Use good case
733- ; ; - Use `PascalCase` for `def` forms
734- ; ; - `camelCase` is not `PascalCase`
741+ ; ; ### Use good case
742+ ; ; - Use `PascalCase` for `def` forms
743+ ; ; - `camelCase` is not `PascalCase`
735744; ; - Acronyms have a consistent case
736745; ; - `url` `:url` `URL`, not `Url`
737746; ; - Therefor `UserID` not `UserId`
738747; ; - Use `::snake-case` or `"PascalCase"` for schema references
739- ; ; - Example
748+ ; ; #### Example
740749; ; ```clojure
741750; ; QueryParams
742751; ; ::query-params
743752; ; ```
744- ; ; - Don't
753+ ; ; #### Don't
745754; ; - `SHOUT-CASE`
746755; ; - Have some style
747756; ; - This is Clojure, everything in `def` is constant anyway
@@ -753,27 +762,31 @@ only-in-encoded
753762
754763; ; Schema references as strings or keywords for custom schema types require a registry, see the cons example above.
755764
756- ; ; - Avoid noisy names
757- ; ; - No need to add a `-schema` suffix to everything
758- ; ; - A good and consistent naming convention can make it clear
759- ; ; - Works well with using a good case
760- ; ; - Compare `User` vs. `USER-SCHEMA`
761- ; ; - This advice is doubly relevant if all the schemas are in a `*.schema` namespace. DRY.
765+ ; ; ### Avoid noisy names
766+ ; ; - No need to add a `-schema` suffix to everything
767+ ; ; - A good and consistent naming convention can make it clear
768+ ; ; - Works well with using a good case
769+ ; ; - Compare `User` vs. `USER-SCHEMA`
770+ ; ; - This advice is doubly relevant if all the schemas are in a `*.schema` namespace. DRY.
762771
763- ; ; - Prefer the narrowest schema
772+ ; ; ## Prefer the narrowest schema
764773; ; - Always ask - does this make sense
774+ ; ; ### Example
775+
765776; ; ```clojure
766777; ; [:map
767778; ; [:messages-recieved int?]]
768779; ; ```
769- ; ; - Example
770- ; ; - Is it possible to have received a negative number of messages?
771- ; ; - Is it legal in our domain model to have received 0?
772- ; ; - `nat-int?` and `pos-int?` are a fit for those cases
780+
781+ ; ; - Is it possible to have received a negative number of messages?
782+ ; ; - Is it legal in our domain model to have received 0?
783+ ; ; - `nat-int?` and `pos-int?` are a fit for those cases
773784
774785; ; ## [Make Illegal States Impossible](https://www.youtube.com/watch?v=IcgmSRJHu_8)
775- ; ; - If you're into that
776- ; ; - Example - Versions
786+
787+ ; ; If you're into that
788+
789+ ; ; #### Example - Versions
777790; ; ```clojure
778791; ; (def Version [:enum 1 2 3])
779792; ; (def MessageV1 [:map [:version Version]])
@@ -783,23 +796,28 @@ only-in-encoded
783796; ; [2 MessageV2]
784797; ; ,,,]
785798; ; ```
786- ; ; - Where's the hole?
787- ; ; - Is this a valid version 1 message?
799+
800+ ; ; Where's the hole?
801+
802+ ; ; Is this a valid version 1 message?
803+
788804; ; ```clojure
789805; ; {:version 3}
790806; ; ```
791- ; ; - Example - optional keys
807+
808+ ; ; #### Example - optional keys
792809; ; - Ingest messages from two sources
793810; ; ```clojure
794811; ; [:map
795812; ; ,,, ;; common
796813; ; :from-a {:optional true} schema-a
797814; ; :from-b {:optional true} schema-b]
798815; ; ```
799- ; ; - Pat ourselves on the back because we cover two options with one schema
800- ; ; - Wrong! This schema covers 4 options, 2 of them are incorrect!
801- ; ; - We can find this out when we generate values
802- ; ; - Split
816+ ; ; Pat ourselves on the back because we cover two options with one schema
817+ ; ; - Wrong! This schema covers 4 options, 2 of them are incorrect!
818+ ; ; - We can find this out when we generate values
819+
820+ ; ; Split:
803821; ; ```clojure
804822; ; (def Common [:map ,,,])
805823; ; (def FromA (mu/merge Common [:map [:from-a schema-a]]))
@@ -849,5 +867,3 @@ pos-int?
849867
850868; ; - Prefer defining new schemas over functions
851869; ; - Prefer decoding over string validation - add a decoder
852-
853-
0 commit comments