#lang racket/base
;; Preserve, as in Fruit Preserve, as in a remarkably weak pun on pickling/dehydration etc

(provide (all-from-out "record.rkt")
         (all-from-out "float.rkt")
         (all-from-out "annotation.rkt")
         (all-from-out "order.rkt")
         (all-from-out "embedded.rkt")
         (all-from-out "merge.rkt")

         (all-from-out "read-binary.rkt")
         (all-from-out "read-text.rkt")
         (all-from-out "write-binary.rkt")
         (all-from-out "write-text.rkt")

         detect-preserve-syntax
         read-preserve
         port->preserves
         file->preserves)

(require racket/match)
(require (only-in racket/file file->list))
(require (only-in racket/port port->list))

(require "record.rkt")
(require "float.rkt")
(require "annotation.rkt")
(require "order.rkt")
(require "embedded.rkt")
(require "merge.rkt")

(require "read-binary.rkt")
(require "read-text.rkt")
(require "write-binary.rkt")
(require "write-text.rkt")

(define (detect-preserve-syntax [in-port (current-input-port)])
  (define b (peek-byte in-port))
  (cond [(eof-object? b) b]
        [(<= #x80 b #xBF) 'binary]
        [else 'text]))

(define (read-preserve [in-port (current-input-port)]
                       #:read-syntax? [read-syntax? #f]
                       #:decode-embedded [decode-embedded #f]
                       #:source [source (object-name in-port)])
  (match (detect-preserve-syntax in-port)
    [(? eof-object? e) e]
    ['binary (read-preserve/binary in-port
                                   #:read-syntax? read-syntax?
                                   #:decode-embedded decode-embedded)]
    ['text (read-preserve/text in-port
                               #:read-syntax? read-syntax?
                               #:decode-embedded decode-embedded
                               #:source source)]))

(define (file->preserves path
                         #:read-syntax? [read-syntax? #f]
                         #:decode-embedded [decode-embedded #f])
  (file->list path (lambda (in-port)
                     (read-preserve in-port
                                    #:read-syntax? read-syntax?
                                    #:decode-embedded decode-embedded
                                    #:source path))))

(define (port->preserves in-port
                         #:read-syntax? [read-syntax? #f]
                         #:decode-embedded [decode-embedded #f]
                         #:source [source (object-name in-port)])
  (port->list (lambda (in-port)
                (read-preserve in-port
                               #:read-syntax? read-syntax?
                               #:decode-embedded decode-embedded
                               #:source source))
              in-port))
