aboutsummaryrefslogtreecommitdiff
path: root/terrafirma.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'terrafirma.lisp')
-rw-r--r--terrafirma.lisp32
1 files changed, 28 insertions, 4 deletions
diff --git a/terrafirma.lisp b/terrafirma.lisp
index 78d74c9..b5ef90c 100644
--- a/terrafirma.lisp
+++ b/terrafirma.lisp
@@ -3,8 +3,10 @@
(defpackage #:terrafirma
(:use #:cl)
(:export
- #:validate
- #:defvalidator))
+ #:validation-error ; Condition
+ #:validate ; Macrolet Symbol
+ #:defvalidator ; Macro
+ ))
(in-package #:terrafirma)
@@ -47,10 +49,31 @@
(defvar *instance*)
(defmacro defvalidator ((var type &key name) &body body)
+ "Defines a validation function. If TYPE is a symbolic type identifier,
+then the defined function will have a name like VALID-<TYPE>-P.
+Otherwise a NAME must be provided.
+
+This means you can define validators for types like (CONS CHAR) if you
+want.
+
+Within the body of DEFVALIDATOR, a special VALIDATE macro is
+bound. Its syntax is:
+
+(VALIDATE CHECK FORMATSTRING &REST FORMATARGS)
+
+E.G.
+
+ (validate (= 10 foo) \"Foo = ~s is not equal to 10\" foo)
+
+A VALIDATE form returns T if CHECK evaluates to non-nil. If CHECK
+signals an error, or if CHECK returns NIL, then the whole validator
+fails.
+
+If all VALIDATE forms pass, then the function returns T."
(assert (and var (symbolp var)) (var) "VAR must be a symbol.")
(let ((validator-name
(cond ((and name (symbolp name)) name)
- ((symbolp type) (intern (format nil "VALIDATED-~a" type)))
+ ((symbolp type) (intern (format nil "VALID-~a-P" type)))
(t (error "Validator Name: Either TYPE must be a symbol or a NAME must be provided.")))))
`(macrolet ((validate (check msg &rest args)
(let ((suberr (gensym)))
@@ -65,4 +88,5 @@
(defun ,validator-name (,var)
(let ((terrafirma::*type* ',type)
(terrafirma::*instance* ,var))
- ,@body)))))
+ ,@body
+ t)))))