Вот я бесконечно далек от концепции рестартов (потому что не кодер). Но всё же я попытался впилить их в свой прожект (сначала это был декодер музыки в flac, а теперь оно ещё и немного понимает wav, а потом, может, будет понимать wavpack и ape).
Итак, ситуация. Вначале flac файла есть метаданные: обязательный блок streaminfo и прочие. Если какие-то блоки моя библиотека не понимает или они битые, то считыватель блока кидает condition 'flac-bad-metadata, а функция выше по стеку предоставляет рестарт: не консить такой блок к возвращаемому списку блоков и поправить позицию потока, из которого идет чтение. Вот код:
(defun open-flac (stream)
;; Checking if stream is flac stream
(let ((bitreader (make-reader :stream stream)))
(if (/= +flac-id+ #+x86_64 (read-bits 32 bitreader)
#-x86_64 (bitreader.be-bignum:read-bits 32 bitreader))
(error 'flac-error :message "Stream is not flac stream"))
(let (metadata-list)
(do (last-block)
(last-block)
(setq last-block
(restart-case
(let ((metadata (metadata-reader bitreader)))
(push metadata metadata-list)
(metadata-last-block-p metadata))
(skip-malformed-metadata (c)
(let ((metadata (flac-metadata c)))
(fix-stream-position bitreader metadata)
(metadata-last-block-p metadata))))))
(values
(reverse metadata-list)
bitreader))))
Так вот вопрос: нормальная ли практика предоставить конечному пользователю функцию open-flac, рестарт (или функцию-обертку) skip-malformed-metadata и condition flac-bad-metadata, чтобы он сам связал этот рестарт с этим условием (т.е. сделал handler-bind) и мог бы точно знать, есть ли у него битые/неизвестные блоки? Или лучше сделать функцию open-flac такой:
(defun open-flac (stream &key skip-malformed) «Если ошибка, то молча пропускаем» ...)? Или есть третий вариант?
Декодер работает и есть на жидхабе, если чё. Ещё он умеет дергать хидер из wav и расжимать g.711.