1 (in-package :lisp-on-lines
)
3 (defclass #.
(defining-description 'validate
) ()
4 ((invalid-object-condition-map :layered t
:special t
))
5 (:metaclass standard-description-class
))
7 (define-layered-class standard-attribute
8 :in-layer
#.
(defining-description 'validate
)
12 :layered-accessor attribute-validators
17 (define-condition validation-condition
()
18 ((format-string :accessor validation-condition-format-string
19 :initarg
:format-string
)
20 (format-args :accessor validation-condition-format-args
21 :initarg
:format-args
)
22 (object :accessor validation-condition-object
24 (attribute :accessor validation-condition-attribute
25 :initarg
:attribute
)))
27 (define-layered-method (setf attribute-value
)
28 :in-layer
#.
(defining-description 'validate
)
29 :around
(value attribute
)
30 (prog1 value
(when (validate-attribute-value attribute value
)
33 (defun validate-attribute-value (attribute value
)
34 (every #'identity
(mapcar (lambda (validator-name)
35 (let ((validator (find-validator validator-name
)))
38 (funcall validator attribute value
)
39 (prog1 t
(warn "Unkown Validator ~A" validator-name
)))))
40 (attribute-validators attribute
))))
43 (defstruct validation-info
(invalid-objects))
45 (defvar *invalid-objects
*)
47 (defvar *validators
* (make-hash-table))
49 (defun register-validator (name fn
)
50 (setf (gethash name
*validators
*) fn
))
52 (defun find-validator (name)
53 (gethash name
*validators
*))
55 (register-validator 'boundp
57 (if (unbound-slot-value-p v
)
59 (signal (make-condition 'validation-condition
60 :format-string
"You must provide a value for ~A"
61 :format-args
(list (attribute-label a
))
63 :object
(attribute-object a
))))
68 (defun validp (object)
69 (with-described-object (object nil
)
70 (every #'identity
(mapcar (lambda (attribute)
71 (validate-attribute-value attribute
(attribute-value attribute
)))
72 (attributes (description-of object
))))))
74 (define-layered-method lol
::display-attribute-editor
75 :in-layer
#.
(defining-description 'validate
)
77 (let ((conditions (remove-if-not
81 (attribute-object attribute
)
82 lol
::*invalid-objects
*)
84 (dolist (c conditions
)
85 (<:div
:style
"color:red"
87 (apply #'format nil
(validation-condition-format-string (cdr c
))
88 (validation-condition-format-args (cdr c
))))))))
92 (defmethod validate-object ((description standard-description-object
) object
)
93 (let (invalid-object?
)
94 (handler-bind ((validation-condition
95 (setf invalid-object? t
))))))