;; SPDX-License-Identifier: EUPL-1.2 ;; SPDX-FileCopyrightText: 2025 Uko Kokņevičs (defpackage :ukkoclot/src/streams (:documentation "Stream-oriented utilities.") (:import-from :serapeum :-> :with-thunk) (:use :c2cl) (:export :call-with-format-like-stream :with-format-like-stream)) (in-package :ukkoclot/src/streams) (-> call-with-format-like-stream ((or stream boolean) (function (stream) t)) t) (defun call-with-format-like-stream (stream-spec fn) "Similar to `with-format-like-stream', but instead of binding the translated stream in a macro body, calls the function `fn' with it." (case stream-spec ((t) (funcall fn *standard-output*) nil) ((nil) (with-output-to-string (stream) (funcall fn stream))) (otherwise (funcall fn stream-spec) nil))) (defmacro with-format-like-stream ((stream-out stream-spec) &body body) "Translates the `stream-spec' into a `stream' similar to how `format' does it and binds it as `stream-out' in `body'. If `stream-spec' is `t': Output to `*standard-output*' and return `nil'. If `stream-spec' is `nil': Output to a string and return it. Else: `stream-spec' must be a stream, output to it and return `nil'" (with-thunk (body stream-out) `(call-with-format-like-stream ,stream-spec ,body)))