Переглянути джерело

simpler query api, parsing conditions

Innocenty Enikeew 8 роки тому
батько
коміт
3684c3d6ad
2 змінених файлів з 29 додано та 3 видалено
  1. 8 2
      package.lisp
  2. 21 1
      pta-ledger.lisp

+ 8 - 2
package.lisp

@@ -1,9 +1,15 @@
 (defpackage #:pta-ledger
   (:use #:cl #:smug)
-  (:export #:parse-journal
+  (:export #:entry
+           #:posting
+           #:parse-journal
            #:parse-query
            #:entries
            #:balance
-           #:format-balance))
+           #:format-balance
+           #:journal-balance
+           #:journal-failed
+           #:parse-error-position
+           #:parse-error-left-data))
 
 (in-package #:pta-ledger)

+ 21 - 1
pta-ledger.lisp

@@ -269,9 +269,25 @@
        (.eol)))))
    (.empty-lines)))
 
+(define-condition journal-failed (error)
+  ((position :initarg :position :reader parse-error-pos)
+   (left-data :initarg :left-data :reader parse-error-left))
+  (:report (lambda (condition stream)
+             (with-slots (position left-data) condition
+               (format stream "Ledger parse failed at position ~A~@[, starting from ~A~]" position left-data)))))
+
 (defun parse-journal (str)
   (let ((*default-year* (car (get-date (get-universal-time)))))
-    (parse (.journal) str)))
+    (multiple-value-bind (result left rest)
+        (parse (.journal) str)
+      (cond
+        ((null result) (error 'journal-failed :left-data (subseq str 0 (min 200 (length str)))))
+        ((not (string= "" left)) (error 'journal-failed
+                                        :position (- (length str)
+                                                     (length left))
+                                        :left-data (subseq left 0 (min 200 (length left)))))
+        ((not (null rest)) (error 'journal-failed :position (length str)))
+        (:otherwise result)))))
 
 (defun .query-coloned (type key-parser value-parser)
   (.let* ((key key-parser)
@@ -534,3 +550,7 @@
                                                       (amount-quantity a)
                                                       (amount-commodity a)))
                                             (rest amounts))))))))
+
+(defun journal-balance (journal &optional query)
+  (format-balance (balance (entries journal)
+                           :predicate (when query (parse-query query)))))