diff --git a/collects/file/convertible.rkt b/collects/file/convertible.rkt new file mode 100644 index 0000000000..6af83fb1d5 --- /dev/null +++ b/collects/file/convertible.rkt @@ -0,0 +1,13 @@ +#lang racket/base + +(provide prop:convertible convertible? convert) + +(define-values (prop:convertible convertible? convertible-ref) + (make-struct-type-property 'convertible)) + +(define (convert v target [default #f]) + (unless (convertible? v) + (raise-type-error 'convert "convertible" 0 v target)) + (unless (symbol? target) + (raise-type-error 'convert "symbol" 1 v target)) + ((convertible-ref v) v target default)) diff --git a/collects/file/scribblings/convertible.scrbl b/collects/file/scribblings/convertible.scrbl new file mode 100644 index 0000000000..7f73554127 --- /dev/null +++ b/collects/file/scribblings/convertible.scrbl @@ -0,0 +1,52 @@ +#lang scribble/doc +@(require scribble/manual + (for-label file/convertible)) + +@title[#:tag "convertible"]{Convertible: Data-Conversion Protocol} + +@defmodule[file/convertible] + +The @schememodname[file/convertible] library provides a protocol to +mediate between providers of data in different possible formats and +consumers of the formats. For example, a datatype that implements +@racket[prop:convertible] might be able to convert itself to a GIF or +PDF stream, in which case it would produce data for +@racket['gif-bytes] or @racket['pdf-bytes] requests. + +Any symbol can be used for a conversion request, but the following +should be considered standard: + +@itemlist[ + #:style 'compact + + @item{@scheme['text] --- a string for human-readable text} + @item{@scheme['gif-bytes] --- a byte string containing a GIF image encoding} + @item{@scheme['png-bytes] --- a byte string containing a PNG image encoding} + @item{@scheme['ps-bytes] --- a byte string containing a PostScript document} + @item{@scheme['pdf-bytes] --- a byte string containing a PDF document} +] + +@defthing[prop:convertible struct-type-property?]{ + +A property whose value should be a procedure of three arguments. The +procedure is called when a structure with the property is passed to +@racket[convert]; the first argument to the procedure is the +structure, the second argument is a symbol for the requested +conversion, and the third argument is a value to return (typically +@racket[#f] if the conversion is not supported. The procedure's result +depends on the requested conversion.} + +@defproc[(convertible? [v any/c]) boolean?]{ + +Returns @racket[#t] if @racket[v] supports the conversion protocol, +@racket[#f] otherwise.} + +@defproc[(convert [v convertible?] [request symbol?] [default any/c #f]) + any]{ + + +Requests a data conversion from @racket[v], where @racket[request] +indicates the type of requested data and @racket[default] is the value +that the converter should return if it cannot produce data in the +format indicated by @racket[request].} + diff --git a/collects/file/scribblings/file.scrbl b/collects/file/scribblings/file.scrbl index be439ecf01..e9ccc91601 100644 --- a/collects/file/scribblings/file.scrbl +++ b/collects/file/scribblings/file.scrbl @@ -5,6 +5,7 @@ @table-of-contents[] +@include-section["convertible.scrbl"] @include-section["gzip.scrbl"] @include-section["gunzip.scrbl"] @include-section["zip.scrbl"]