Liking cljdoc? Tell your friends :D

macaw.util.malli.fn


*enforce*clj

Whether validate-input and validate-output should validate things or not.

Whether [[validate-input]] and [[validate-output]] should validate things or not.
sourceraw docstring

deparameterized-fn-formclj

(deparameterized-fn-form parsed & [fn-name])

Impl for macaw.util.malli.fn/fn and macaw.util.malli.defn/defn. Given a parsed fn tail (as parsed by [[parsed-fn-tail]]), return a [[clojure.core.fn]] form with the parameters stripped out.

(deparameterized-fn-form (parse-fn-tail '[:- :int [x :- :int] (inc x)])) ;; => (fn [x] (inc x))

Impl for [[macaw.util.malli.fn/fn]] and [[macaw.util.malli.defn/defn]]. Given a parsed `fn` tail (as parsed
by [[parsed-fn-tail]]), return a [[clojure.core.fn]] form with the parameters stripped out.

  (deparameterized-fn-form (parse-fn-tail '[:- :int [x :- :int] (inc x)]))
  ;; =>
  (fn [x] (inc x))
sourceraw docstring

deparameterized-fn-tailclj

(deparameterized-fn-tail {[arities-type arities-value] :arities :as _parsed})

Generate a deparameterized fn tail (the contents of a fn form after the fn symbol).

Generate a deparameterized `fn` tail (the contents of a `fn` form after the `fn` symbol).
sourceraw docstring

fixup-stacktraceclj

(fixup-stacktrace e)

If exception is thrown from the [[validate]] machinery, remove those stack trace elements so the top of the stack is the calling function.

If exception is thrown from the [[validate]] machinery, remove those stack trace elements so the top of the stack is
the calling function.
sourceraw docstring

fncljmacro

(fn & fn-tail)

Malli version of [[schema.core/fn]].

Unless it's in a skipped namespace during prod, a form like:

(fn :- :int [x :- :int] (inc x))

compiles to something like

(let [&f (fn [x] (inc x))] (fn [a] (validate-input {} :int a) (validate-output {} :int (&f a))))

The map arg here is additional error context; for something like macaw.util.malli/defn, it will be something like

{:fn-name 'metabase.lib.field/resolve-field-id}

If compiled in a namespace in [[namespaces-toskip]], during config/is-prod?, it will be emitted as a vanilla clojure.core/fn form.

Known issue: this version of fn does not capture the optional function name and make it available, e.g. you can't do

(mu/fn my-fn ([x] (my-fn x 1)) ([x y :- :int] (+ x y)))

If we were to include my-fn in the uninstrumented fn form, then it would bypass schema checks when you call another arity:

(let [&f (fn my-fn ([x] (my-fn x 1)) ([x y] (+ x y)))] (fn ([a] (&f a)) ([a b] (validate-input {} :int b) (&f a b))))

;; skips the :- :int check on y in the 2-arity (my-fn 1.0) ;; => 2.0

Since this is a big gotcha, we are currently not including the optional function name my-fn in the generated output. We can probably fix this with [[letfn]], since it allows mutually recursive function calls, but that's a problem for another day. The passed function name comes back from [[mc/parse]] as :name if we want to attempt to fix this later.

Malli version of [[schema.core/fn]].

Unless it's in a skipped namespace during prod, a form like:

  (fn :- :int [x :- :int] (inc x))

compiles to something like

  (let [&f (fn [x] (inc x))]
    (fn [a]
      (validate-input {} :int a)
      (validate-output {} :int (&f a))))

The map arg here is additional error context; for something like [[macaw.util.malli/defn]], it will be something
like

  {:fn-name 'metabase.lib.field/resolve-field-id}

If compiled in a namespace in [[namespaces-toskip]], during `config/is-prod?`, it will be emitted as a vanilla
clojure.core/fn form.

Known issue: this version of `fn` does not capture the optional function name and make it available, e.g. you can't
do

  (mu/fn my-fn
   ([x] (my-fn x 1))
   ([x y :- :int] (+ x y)))

If we were to include `my-fn` in the uninstrumented `fn` form, then it would bypass schema checks when you call
another arity:

  (let [&f (fn my-fn
             ([x] (my-fn x 1))
             ([x y] (+ x y)))]
    (fn
      ([a]
       (&f a))
      ([a b]
       (validate-input {} :int b)
       (&f a b))))

  ;; skips the `:- :int` check on `y` in the 2-arity
  (my-fn 1.0) ;; => 2.0

Since this is a big gotcha, we are currently not including the optional function name `my-fn` in the generated
output. We can probably fix this with [[letfn]], since it allows mutually recursive function calls, but that's a
problem for another day. The passed function name comes back from [[mc/parse]] as `:name` if we want to attempt to
fix this later.
sourceraw docstring

fn-schemaclj

(fn-schema parsed)
(fn-schema parsed options)

Implementation for fn and macaw.util.malli.defn/defn. Given an unparsed parametered fn tail, extract the annotations and return a :=> or :function schema.

options can contain :target which is either

  • :target/metadata: generate the schema to attach to the metadata for a macaw.util.malli.defn/defn. For key-value varargs like & {:as kvs} get a schema like [:* :any] in this case since the args aren't parsed to a map yet

  • :target/instrumentation: generate a schema for use in generating the instrumented fn form. & {:as kvs} can have a real map schema here.

Implementation for [[fn]] and [[macaw.util.malli.defn/defn]]. Given an unparsed parametered fn tail, extract the
annotations and return a `:=>` or `:function` schema.

`options` can contain `:target` which is either

* `:target/metadata`: generate the schema to attach to the metadata for a [[macaw.util.malli.defn/defn]]. For
  key-value varargs like `& {:as kvs}` get a schema like `[:* :any]` in this case since the args aren't parsed to a
  map yet

* `:target/instrumentation`: generate a schema for use in generating the instrumented `fn` form. `& {:as kvs}` can
  have a real map schema here.
sourceraw docstring

instrument-ns?clj

(instrument-ns? namespace)

Returns true if mu.fn/fn and mu/defn in a namespace should be instrumented with malli schema validation.

Returns true if mu.fn/fn and mu/defn in a namespace should be instrumented with malli schema validation.
sourceraw docstring

instrumented-fn-formclj

(instrumented-fn-form error-context parsed & [fn-name])

Given a fn-tail like

([x :- :int y] (+ 1 2))

and parsed by [[parsed-fn-tail]],

return an unevaluated instrumented fn form like

(mc/-instrument {:schema [:=> [:cat :int :any] :any]} (fn [x y] (+ 1 2)))

Given a `fn-tail` like

  ([x :- :int y] (+ 1 2))

and parsed by [[parsed-fn-tail]],

return an unevaluated instrumented [[fn]] form like

  (mc/-instrument {:schema [:=> [:cat :int :any] :any]}
                  (fn [x y] (+ 1 2)))
sourceraw docstring

parse-fn-tailclj

(parse-fn-tail fn-tail)

Parse a parameterized fn tail with the [[SchematizedParams]] schema. Throw an exception if it cannot be parsed.

Parse a parameterized `fn` tail with the [[SchematizedParams]] schema. Throw an exception if it cannot be parsed.
sourceraw docstring

validate-inputclj

(validate-input error-context schema value)

Impl for macaw.util.malli.fn/fn; validates an input argument with value against schema using a cached explainer and throws an exception if the check fails.

Impl for [[macaw.util.malli.fn/fn]]; validates an input argument with `value` against `schema` using a cached
explainer and throws an exception if the check fails.
sourceraw docstring

validate-outputclj

(validate-output error-context schema value)

Impl for macaw.util.malli.fn/fn; validates function output value against schema using a cached explainer and throws an exception if the check fails. Returns validated value.

Impl for [[macaw.util.malli.fn/fn]]; validates function output `value` against `schema` using a cached explainer
and throws an exception if the check fails. Returns validated value.
sourceraw docstring

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close