{"id":26119486,"url":"https://github.com/mmontone/clavier","last_synced_at":"2026-02-14T10:33:04.158Z","repository":{"id":16416845,"uuid":"19167954","full_name":"mmontone/clavier","owner":"mmontone","description":":heavy_check_mark: General purpose validation library for Common Lisp","archived":false,"fork":false,"pushed_at":"2025-04-17T18:15:25.000Z","size":49,"stargazers_count":26,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-09-09T20:13:14.407Z","etag":null,"topics":["common-lisp","lisp","utilities","validation"],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mmontone.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2014-04-26T03:41:05.000Z","updated_at":"2025-08-23T13:31:30.000Z","dependencies_parsed_at":"2024-05-02T11:07:38.557Z","dependency_job_id":"28fbb309-8bc7-4ed1-a4c5-ecbfd2484d15","html_url":"https://github.com/mmontone/clavier","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mmontone/clavier","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmontone%2Fclavier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmontone%2Fclavier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmontone%2Fclavier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmontone%2Fclavier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mmontone","download_url":"https://codeload.github.com/mmontone/clavier/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmontone%2Fclavier/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29442749,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T10:17:46.583Z","status":"ssl_error","status_checked_at":"2026-02-14T10:17:22.534Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["common-lisp","lisp","utilities","validation"],"created_at":"2025-03-10T12:55:11.845Z","updated_at":"2026-02-14T10:33:04.143Z","avatar_url":"https://github.com/mmontone.png","language":"Common Lisp","readme":"Clavier\n----------\n\n[![Quicklisp](http://quickdocs.org/badge/clavier.svg)](http://quickdocs.org/clavier/)\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)\n\n*Clavier* is a general purpose validation library for Common Lisp.\n\nInstall\n-------\n\nThrough Quicklisp:\n\n```lisp\n(ql:quickload :clavier)\n```\nGetting started\n---------------\n\nValidators are class instances that validate the arguments passed to the `validate` function:\n\n```lisp\n(let ((validator (make-instance 'equal-to-validator :object 22)))\n    (validate validator 22 :error-p t))\n    \n;=\u003e T\n```\n\nIf the validator succeeds, the validate function returns `T`. If it fails, the validate function either signals a validation error, or returns `NIL` and a validation message depending on the value of the `:error-p` argument.\n\n```lisp\n(let ((validator (make-instance 'equal-to-validator :object 22)))\n    (validate validator 33 :error-p nil))\n    \n;=\u003e\n;NIL    \n;\"33 is not equal to 22\"\n```\n\nValidators are implemented as funcallable classes. So, alternatively to using the `validate` function, it is possible to just funcall the validator, like this:\n\n```lisp\n(let ((validator (make-instance 'equal-to-validator :object 22)))\n    (funcall validator 22 :error-p t))\n    \n;=\u003e T\n```\n\n## Validation expressions\n\nIt is possible to create validators with a more convenient syntax. Each validator provides a builder function. For instance, and equal-to-validator can be built like this:\n\n```lisp\n(funcall (== 100) 100) ;=\u003e T\n(funcall (== 100) 99) ;=\u003e NIL\n```\n\n## Validators composition\n\nThis allows to compose validators, using `==`, `~=`, `\u0026\u0026`, `||` as the composition operands:\n\n```lisp\n(let ((validator (|| (\u0026\u0026 (greater-than 20)\n\t\t\t   (less-than 30))\n\t\t       (|| (\u0026\u0026 (greater-than 1)\n\t\t\t       (less-than 10))\n\t\t\t   (== 100)))))\n    (funcall validator 5))\n```\n\nFor example, this is how to accept a blank object, but validate it if it isn't blank:\n\n\n~~~lisp\n(defparameter *validator* (clavier:||\n                                   (clavier:blank)\n                                   (clavier:\u0026\u0026 (clavier:is-a-string)\n                                               (clavier:len :min 10)))\n  \"Allow a blank value. When non blank, validate.\")\n\n(funcall *validator* \"\")\n;; =\u003e\nT\nNIL\n\n(funcall *validator* \"asdfasdfasdf\")\n;; =\u003e\nT\nNIL\n\n(funcall *validator* \"asdf\")\n;; =\u003e\nNIL\n\"Length of \\\"asdf\\\" is less than 10\"\n\n(funcall *validator* 2)\n;; =\u003e\nNIL\n\"2 is not a string\"\n~~~\n\n\n## Validators messages\n\nValidators messages to be used when validation fails can be customized passing an `:message` argument when building the validator\n\n## Catching and collecting validation errors\n\nValidation errors can be controlled globally by setting the dynamic variable `*signal-validation-errors*`, which is `NIL` by default (no validation errors are signaled by default).\n\nThere's also the `with-signal-validation-errors` macro to specify whether validation errors should be signaled or not in a dynamic extent. For instance, this code signals a validation error:\n\n```lisp\n(let ((validator (make-instance 'equal-to-validator :object 22)))\n\t   (with-signal-validation-errors (t)\n\t     (validate validator 33)))\n```\n\nUse the `collecting-validation-errors` macro to collect validation errors happening in a dynamic extent:\n\n```lisp\n(let ((validator (make-instance 'equal-to-validator :object 22)))\n\t   (collecting-validation-errors (errors found-p)\n\t       (progn\n\t\t (funcall validator 33 :error-p t)\n\t\t (funcall validator 44 :error-p t))\n\t     (print errors)\n\t     (print found-p)))\n;=\u003e\n;(#\u003cVALIDATION-ERROR 44: 44 is not equal to 22 {1008A48673}\u003e\n; #\u003cVALIDATION-ERROR 33: 33 is not equal to 22 {1008A47EA3}\u003e) \n;T \n```\n\n## Validators list:\n\nThis is the list of available validator classes and their shortcut function:\n\n* equal-to-validator `(==)`\n* not-equal-to-validator `(~=)`\n* blank-validator `(blank)`\n* not-blank-validator `(not-blank)`\n* true-validator `(is-true)`\n* false-validator `(is-false)`\n* type-validator `(is-a type)`\n* string-validator `(is-a-string)`\n* boolean-validator `(is-a-boolean)`\n* integer-validator `(is-an-integer)`\n* symbol-validator `(is-a-symbol)`\n* keyword-validator `(is-a-keyword)`\n* list-validator `(is-a-list)`\n* function-validator `(fn function message)`\n* email-validator `(valid-email)`\n* regex-validator `(matches-regex regex-pattern)`\n* url-validator `(valid-url)`\n* datetime-validator `(valid-datetime)`\n* pathname-validator `(valid-pathname)`\n* not-validator `(~ validator)`\n* and-validator `(\u0026\u0026 validator1 validator2)`\n* or-validator `(|| validator1 validator2)`\n* one-of-validator `(one-of options)`\n* less-than-validator `(less-than number)`\n* greater-than-validator `(greater-than number)`\n* length-validator `(len)`\n","funding_links":[],"categories":["Python ##","Online editors ##"],"sub_categories":["Third-party APIs"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmontone%2Fclavier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmmontone%2Fclavier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmontone%2Fclavier/lists"}