+ :initform nil)
+ (attribute-editor
+ :initarg :input
+ :layered t
+ :accessor attribute-editor
+ :initform nil
+ :documentation "This ones a bit odd")))
+
+(defmethod attribute-editor :around (attribute)
+ (flet ((find-editor-class (spec)
+ (let ((class (getf spec :class))
+ (type (getf spec :type)))
+ (or class (when (and type (symbolp type))
+ (intern (format nil "~A-~A" type 'attribute-editor)))
+ 'string-attribute-editor))))
+ (let ((editor? (call-next-method)))
+ (if (listp editor?)
+ (setf (attribute-editor attribute)
+ (apply #'make-instance (find-editor-class editor?)
+ editor?))
+ (call-next-method)))))
+
+
+(defclass attribute-editor ()
+ ((type :initarg :type
+ :initform 'string)
+ (parser :initarg :parse-using
+ :initform 'identity
+ :accessor attribute-editor-parsing-function)
+ (prompt :initarg :prompt
+ :initform nil)))
+
+(defclass string-attribute-editor (attribute-editor) ())
+(defclass text-attribute-editor (string-attribute-editor) ())
+(defclass password-attribute-editor (string-attribute-editor) ())
+
+(defclass number-attribute-editor (attribute-editor) ()
+ (:default-initargs
+ :parse-using 'parse-number:PARSE-NUMBER
+ :type 'number))
+
+(defun parse-attribute-value (attribute value)
+ (funcall (attribute-editor-parsing-function
+ (attribute-editor attribute))
+ value))