Files
cl-xdg-trash/trashinfo.lisp
2025-09-30 14:29:54 -07:00

75 lines
3.1 KiB
Common Lisp

(in-package :cl-xdg-trash/trashinfo)
(define-condition trashinfo-format-error (error)
((message :accessor trashinfo-format-error-message
:initarg :message
:type string
:documentation "A message describing the error.")
(line-number :accessor trashinfo-format-error-line-number
:initarg :line-number
:type (integer 1)
:documentation "The line number of the error. The first line is
line 1.")
(context :accessor trashinfo-format-error-context
:initarg :context
:type string
:documentation "The text of the line causing the error.")
(source-file :accessor trashinfo-format-error-source-file
:initarg :source-file
:type pathname
:documentation "The path to the file the error happened in."))
(:report (lambda (condition stream)
(with-slots (message line-number source-file) condition
(format stream "Error parsing ~A on line ~A: ~A."
source-file line-number message)))))
(defclass trashinfo ()
((trash-directory :reader trashinfo-trash-directory
:initarg :trash-directory
:type pathname
:documentation "The path to the trash directory that this
trashinfo file belongs to.")
(name :accessor trashinfo-name
:initarg :name
:type string
:documentation "The name of this trashinfo file without the extension.")
(path :accessor trashinfo-path
:initarg :path
:type pathname
:documentation "Path to the original location of the file.")
(deletion-date :accessor trashinfo-deletion-date
:initarg :deletion-date
:type local-time:timestamp
:documentation "The time the corresponding file was
trashed."))
(:documentation "Represents a .trashinfo file."))
(declaim (ftype (function ((or pathname string) string) trashinfo)))
(defun parse-trashinfo-from-string (trash-directory name)
"Parse the trashinfo file NAME (which should not have an extension) in
TRASH-DIRECTORY."
(let ((source-file (merge-pathnames (make-pathname :name name
:directory '(:relative "info"))
trash-directory)))
(with-open-file (in source-file :if-does-not-exist :error)
(let ((first-line (read-line in :eof-error-p nil)))
(unless first-line
(error 'trashinfo-format-error
:line-number 1 :source-file source-file
:context "" :message "Unexpected end-of-file"))
(unless (equal first-line "[Trash Info]")
(error 'trashinfo-format-error
:line-number 1 :source-file source-file
:context first-line
:message "First line should be \"[Trash Info]\"")))
(loop for line = (read-line in :eof-error-p nil)
while line)
)))
(defmethod trashinfo-trashed-file ())
;; Local Variables:
;; jinx-local-words: "trashinfo"
;; End: