#lang mzscheme
(require scheme/contract
(all-except srfi/1/list any)
srfi/13/string
srfi/19/time
srfi/26/cut)
(require (planet "aif.ss" ("schematics" "macro.plt" 1)))
(require (file "base.ss")
(file "parameter.ss")
(file "time.ss"))
(define-struct log-stream (name) #f)
(define make-log make-log-stream)
(define message-log (make-log 'M))
(define warning-log (make-log 'W))
(define error-log (make-log 'E))
(define-parameter current-log-preamble
(lambda () null)
(lambda (val)
(if (procedure? val)
val
(raise-exn exn:fail:unlib
(format "Expected (symbol -> (list-of string)), received ~a." val))))
with-log-preamble)
(define-parameter current-log-port
current-output-port
(lambda (val)
(if (output-port? val)
val
(raise-exn exn:fail:unlib
(format "Expected output-port, received ~a." val))))
with-log-port)
(define log-message
(lambda args
(log-generic message-log args)))
(define log-warning
(lambda args
(log-generic warning-log args)))
(define log-error
(lambda args
(log-generic error-log args)))
(define log-generic
(lambda (log-stream message-components)
(let* ([time (current-time time-tai)]
[items (cons (log-stream-name log-stream)
(append ((current-log-preamble)) message-components))]
[out (aif log-port parameter? (current-log-port)
(log-port)
log-port)])
(display (string-join (map (cut format "~s" <>) items) ",") out)
(newline out)
time)))
(provide with-log-preamble
with-log-port)
(provide/contract
[struct log-stream ([name symbol?])]
[make-log (-> symbol? log-stream?)]
[message-log log-stream?]
[warning-log log-stream?]
[error-log log-stream?]
[current-log-preamble (parameter/c procedure?)]
[current-log-port (parameter/c output-port?)]
[log-message (->* () () #:rest any/c time-tai?)]
[log-warning (->* () () #:rest any/c time-tai?)]
[log-error (->* () () #:rest any/c time-tai?)]
[log-generic (-> log-stream? list? time-tai?)])