Application service and state management. Holds long-lived references (database connections, env, etc.) that should persist across tools.namespace reloads. Services are maps of {:start sym :stop sym} started/stopped via start!/stop!.
Application service and state management. Holds long-lived references (database connections, env, etc.) that should persist across `tools.namespace` reloads. Services are maps of `{:start sym :stop sym}` started/stopped via `start!`/`stop!`.
Cross-platform benchmarking macros: elapsed-time for one-shot timing, bench for repeated runs returning {:min :max :total :avg} in milliseconds.
Cross-platform benchmarking macros: `elapsed-time` for one-shot timing, `bench` for repeated runs returning `{:min :max :total :avg}` in milliseconds.
Common core code. This file should have minimal dependencies. Clients should be able to safely :refer :all from this namespace.
Common core code. This file should have minimal dependencies. Clients should be able to safely :refer :all from this namespace.
Defines a Cursor that wraps an atom (or atom-like structure) and provides a way to focus on a specific path within its nested data. It implements various Clojure interfaces to make it behave like an atom itself, with dereferencing, swapping, resetting, and watching capabilities.
Defines a Cursor that wraps an atom (or atom-like structure) and provides a way to focus on a specific path within its nested data. It implements various Clojure interfaces to make it behave like an atom itself, with dereferencing, swapping, resetting, and watching capabilities.
Resolves configuration values from (in order): runtime overrides via override!, Java system properties, OS environment variables, and an optional .env Properties file at the project root.
Resolves configuration values from (in order): runtime overrides via `override!`, Java system properties, OS environment variables, and an optional `.env` Properties file at the project root.
Registry mapping :kind keywords to their conformed schemas. Provides for-kind lookup and throwing variants of schema's present!/coerce!/conform! that auto-resolve the schema from (:kind entity).
Registry mapping `:kind` keywords to their conformed schemas. Provides `for-kind` lookup and throwing variants of schema's `present!`/`coerce!`/`conform!` that auto-resolve the schema from `(:kind entity)`.
Cross-platform logging facade over Timbre. Re-exports level macros (info, warn, etc.), level controls (info!, off!, etc.), and a capture-logs helper for asserting log output in tests.
Cross-platform logging facade over Timbre. Re-exports level macros (`info`, `warn`, etc.), level controls (`info!`, `off!`, etc.), and a `capture-logs` helper for asserting log output in tests.
Workflow-aware namespace reloading. Wraps clojure.tools.namespace so that
registered services (see c3kit.apron.app) are stopped before reload and
restarted after, keeping app state coherent during interactive development.
Workflow-aware namespace reloading. Wraps `clojure.tools.namespace` so that registered services (see `c3kit.apron.app`) are stopped before reload and restarted after, keeping app state coherent during interactive development.
Defines data structure, coerces, validates.
Defines data structure, coerces, validates.
Pure coercion helpers and constructors used by both c3kit.apron.schema and c3kit.apron.schema.coercions. Owns no lexicon state — coercion lexes are bundled in c3kit.apron.schema.coercions and merged into the default lexicon by c3kit.apron.schema.
Named with the plural suffix to avoid the CLJS namespace/var clash with c3kit.apron.schema/coerce (the entity-level public fn).
Pure coercion helpers and constructors used by both c3kit.apron.schema and c3kit.apron.schema.coercions. Owns no lexicon state — coercion lexes are bundled in c3kit.apron.schema.coercions and merged into the default lexicon by c3kit.apron.schema. Named with the plural suffix to avoid the CLJS namespace/var clash with c3kit.apron.schema/coerce (the entity-level public fn).
Standard coercion lexes. Each lex is its own var for à-la-carte use; default-coercions bundles them as a {name → lex} map that c3kit.apron.schema merges into the default lexicon at its load. This namespace is pure data — it does not require c3kit.apron.schema.
Standard coercion lexes. Each lex is its own var for à-la-carte use;
default-coercions bundles them as a {name → lex} map that
c3kit.apron.schema merges into the default lexicon at its load.
This namespace is pure data — it does not require c3kit.apron.schema.Shared infrastructure for doc-format renderers (OpenAPI, markdown, ...). Describes the expected shape of a route/doc spec and provides helpers that are format-agnostic.
Shared infrastructure for doc-format renderers (OpenAPI, markdown, ...). Describes the expected shape of a route/doc spec and provides helpers that are format-agnostic.
Coordinate-based traversal of schemas and data. The grammar matches what schema/message-seq produces:
For schemas, two reserved segment names provide access to dynamic templates:
If the spec has no matching template (e.g. a :map with no :value-spec), :value and :key fall back to ordinary field lookup in :schema.
schema-at walks a schema tree (template semantics). data-at walks concrete data (supports an optional :lenient? option for keyword/string key equivalence).
Coordinate-based traversal of schemas and data. The grammar matches what schema/message-seq produces: - dot-separated keyword keys: a.b.c - [N] for seq indices: points[0] - ["..."] for string keys: crew["bill"] - [:kw] for explicit keywords: a[:joe] For schemas, two reserved segment names provide access to dynamic templates: - :value — the :value-spec of a :map, or the :spec of a :seq - :key — the :key-spec of a :map If the spec has no matching template (e.g. a :map with no :value-spec), :value and :key fall back to ordinary field lookup in :schema. schema-at walks a schema tree (template semantics). data-at walks concrete data (supports an optional :lenient? option for keyword/string key equivalence).
Standard presentation lexes. Each lex is its own var for à-la-carte use; default-presentations bundles them as a {name → lex} map that c3kit.apron.schema merges into the default lexicon at its load. This namespace is pure data — it does not require c3kit.apron.schema.
A presentation lex has the shape {:present fn} — no :message, since presentations don't fail in the lex-error sense; they just transform. If a present-fn throws, that's a bug at the call site; exceptions propagate rather than being captured as field errors.
Standard presentation lexes. Each lex is its own var for à-la-carte
use; default-presentations bundles them as a {name → lex} map that
c3kit.apron.schema merges into the default lexicon at its load.
This namespace is pure data — it does not require c3kit.apron.schema.
A presentation lex has the shape {:present fn} — no :message, since
presentations don't fail in the lex-error sense; they just transform.
If a present-fn throws, that's a bug at the call site; exceptions
propagate rather than being captured as field errors.Standard type lexes. A type lex has shape
{:validations [...] ; lex names / factory vectors / inline maps — run as type-level validation :coercions [...]} ; lex names / factory vectors / inline maps / bare fns — run as type-level coercion
default-types bundles them as a {name → lex} map that c3kit.apron.schema merges into the default lexicon at its load.
---- shape choice for default types ----
Default types' :validations use inline {:validate fn :message msg} maps rather than composed [:maybe? :foo?] lex references. The composed form reads more elegantly but costs a few lexicon lookups per validation pass; the inline form pays nothing.
Both shapes follow the same message precedence (entry's :message wins, spec :message is a fallback), so the choice between them is just about runtime cost vs. composition style.
:coercions use bare coercer fns so that coerce-ex's specific 'can't coerce VALUE to TYPE' message reaches the caller. Named coercion lexes there would substitute the lex's generic 'could not coerce to int' message instead.
User-defined types are free to use either form for either slot.
---- nil tolerance ----
Default types allow nil by wrapping the type predicate in (validators/nil?-or ...). Users who want strict non-nil checking add :present? to their spec's :validations.
---- structural types ----
:one-of, :seq, and :map are structural — c3kit.apron.schema's process-spec-on-value dispatches on them before the type lex's validations / coercions would run. They're included here so the lex names resolve and conform-schema! recognizes them as valid types.
This namespace is pure data; it does not require c3kit.apron.schema.
Standard type lexes. A type lex has shape
{:validations [...] ; lex names / factory vectors / inline maps — run as type-level validation
:coercions [...]} ; lex names / factory vectors / inline maps / bare fns — run as type-level coercion
default-types bundles them as a {name → lex} map that
c3kit.apron.schema merges into the default lexicon at its load.
---- shape choice for default types ----
Default types' :validations use inline {:validate fn :message msg}
maps rather than composed [:maybe? :foo?] lex references. The
composed form reads more elegantly but costs a few lexicon lookups
per validation pass; the inline form pays nothing.
Both shapes follow the same message precedence (entry's :message
wins, spec :message is a fallback), so the choice between them is
just about runtime cost vs. composition style.
:coercions use bare coercer fns so that coerce-ex's specific
'can't coerce VALUE to TYPE' message reaches the caller. Named
coercion lexes there would substitute the lex's generic
'could not coerce to int' message instead.
User-defined types are free to use either form for either slot.
---- nil tolerance ----
Default types allow nil by wrapping the type predicate in
(validators/nil?-or ...). Users who want strict non-nil checking
add :present? to their spec's :validations.
---- structural types ----
:one-of, :seq, and :map are structural — c3kit.apron.schema's
process-spec-on-value dispatches on them before the type lex's
validations / coercions would run. They're included here so the
lex names resolve and conform-schema! recognizes them as valid
types.
This namespace is pure data; it does not require c3kit.apron.schema.Standard validation lexes. Each lex is its own var for à-la-carte use; default-validations bundles them as a {name → lex} map that c3kit.apron.schema merges into the default lexicon at its load. This namespace is pure data — it does not require c3kit.apron.schema.
Standard validation lexes. Each lex is its own var for à-la-carte use;
default-validations bundles them as a {name → lex} map that
c3kit.apron.schema merges into the default lexicon at its load.
This namespace is pure data — it does not require c3kit.apron.schema.Pure validation helpers — predicates, combinator factories, and the minimal building blocks used by both c3kit.apron.schema and c3kit.apron.schema.validations. Owns no lexicon state; combinators call out through validation-resolver, which c3kit.apron.schema populates at load time, to avoid a require cycle.
Named with the plural suffix to avoid the CLJS namespace/var clash with c3kit.apron.schema/validate (the entity-level public fn).
Pure validation helpers — predicates, combinator factories, and the minimal building blocks used by both c3kit.apron.schema and c3kit.apron.schema.validations. Owns no lexicon state; combinators call out through *validation-resolver*, which c3kit.apron.schema populates at load time, to avoid a require cycle. Named with the plural suffix to avoid the CLJS namespace/var clash with c3kit.apron.schema/validate (the entity-level public fn).
Truth is like the sun. You can shut it out for a time, but it ain't goin' away.
Truth is like the sun. You can shut it out for a time, but it ain't goin' away.
Cross-platform time/date manipulation. JVM uses java.util.Date; CLJS uses cljs-time. The atomic unit throughout is the millisecond.
Cross-platform time/date manipulation. JVM uses `java.util.Date`; CLJS uses `cljs-time`. The atomic unit throughout is the millisecond.
JVM-only utilities: filesystem traversal, namespace/path conversion, MD5 hashing, EDN resource reading, and dynamic var resolution.
JVM-only utilities: filesystem traversal, namespace/path conversion, MD5 hashing, EDN resource reading, and dynamic var resolution.
Cross-platform conversions: EDN, transit, JSON (JVM), hex, CSV, plus shared collection helpers that work in both Clojure and ClojureScript.
Cross-platform conversions: EDN, transit, JSON (JVM), hex, CSV, plus shared collection helpers that work in both Clojure and ClojureScript.
Ring middleware (wrap-verbose) that pretty-prints request and response maps to the log for development debugging.
Ring middleware (`wrap-verbose`) that pretty-prints request and response maps to the log for development debugging.
Runtime access to the apron version string.
Runtime access to the apron version string.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |