Factor out parse-metadata in preparation for real error-handling.

This commit is contained in:
Brit Butler 2014-09-03 14:34:53 -04:00
parent 2bd647207a
commit 2ed12c5bce
2 changed files with 20 additions and 16 deletions

View file

@ -248,7 +248,7 @@ at best, especially for anyone not coming from the lisp world.
We need to start handling errors and reporting errors in ways We need to start handling errors and reporting errors in ways
that are useful to the user. Example errors users have encountered: that are useful to the user. Example errors users have encountered:
1. Loading of Content. If `read-content` fails to parse a file, wen 1. Loading of Content. If `read-content` fails to parse a file, we
should tell the user what file failed and why. We also should should tell the user what file failed and why. We also should
probably enforce more constraints about metadata. E.g. Empty probably enforce more constraints about metadata. E.g. Empty
metadata is not allowed/meaningful. Trailing space after separator, etc. metadata is not allowed/meaningful. Trailing space after separator, etc.

View file

@ -48,27 +48,31 @@
(when (stringp tags) (when (stringp tags)
(setf tags (mapcar #'make-tag (cl-ppcre:split "," tags)))))) (setf tags (mapcar #'make-tag (cl-ppcre:split "," tags))))))
(defun parse-metadata (stream)
"Given a STREAM, parse metadata from it or signal an appropriate condition."
(flet ((parse-field (str)
(nth-value 1 (cl-ppcre:scan-to-strings "[a-zA-Z]+:\\s+(.*)" str)))
(field-name (line)
(make-keyword (string-upcase (subseq line 0 (position #\: line))))))
(unless (string= (read-line stream nil) (separator *config*))
(error "The provided file lacks the expected header."))
(loop for line = (read-line stream nil)
until (string= line (separator *config*))
appending (list (field-name line)
(aref (parse-field line) 0)))))
(defun read-content (file) (defun read-content (file)
"Returns a plist of metadata from FILE with :text holding the content as a string." "Returns a plist of metadata from FILE with :text holding the content."
(flet ((slurp-remainder (stream) (flet ((slurp-remainder (stream)
(let ((seq (make-string (- (file-length stream) (let ((seq (make-string (- (file-length stream)
(file-position stream))))) (file-position stream)))))
(read-sequence seq stream) (read-sequence seq stream)
(remove #\Nul seq))) (remove #\Nul seq))))
(parse-field (str)
(nth-value 1 (cl-ppcre:scan-to-strings "[a-zA-Z]+:\\s+(.*)" str)))
(field-name (line)
(make-keyword (string-upcase (subseq line 0 (position #\: line))))))
(with-open-file (in file :external-format '(:utf-8)) (with-open-file (in file :external-format '(:utf-8))
(unless (string= (read-line in) (separator *config*)) (let ((metadata (parse-metadata in))
(error "The provided file lacks the expected header.")) (content (slurp-remainder in))
(let ((meta (loop for line = (read-line in nil) (filepath (enough-namestring file (repo *config*))))
until (string= line (separator *config*)) (append metadata (list :text content :file filepath))))))
appending (list (field-name line)
(aref (parse-field line) 0))))
(filepath (enough-namestring file (repo *config*)))
(content (slurp-remainder in)))
(append meta (list :text content :file filepath))))))
;; Helper Functions ;; Helper Functions