(defmacro define-binary-type (name (&rest args) &body spec) (alexandria:with-gensyms (type) `(progn ,(destructuring-bind ((in) &body body) (rest (assoc :reader spec)) `(defmethod read-value ((,type (eql ',name)) ,in &key ,@args) ,@body)) ,(destructuring-bind ((out value) &body body) (rest (assoc :writer spec)) `(defmethod write-value ((,type (eql ',name)) ,out ,value &key ,@args) ,@body))))) (trivial-indent:define-indentation define-binary-type (4 4 &rest (&whole 2 4 4 &body))) ;; produces the following indentation: (define-binary-type iso-8859-1-string (length) (:reader (in) (let ((string (make-string length))) (dotimes (i length) (setf (char string i) (code-char (read-byte in)))) string)) (:writer (out string) (dotimes (i length) (write-byte (char-code (char string i)) out))))