racket/collects/unstable/dirs.rkt
2010-04-27 16:50:15 -06:00

69 lines
2.3 KiB
Racket

#lang racket/base
;; Unstable library by: Carl Eastlund <cce@ccs.neu.edu>
;; intended for use in racket/contract, so don't try to add contracts!
(require racket/dict
setup/path-relativize
setup/dirs
(only-in planet/config [CACHE-DIR find-planet-dir]))
(provide path->directory-relative-string
library-relative-directories
setup-relative-directories)
(define library-relative-directories
(list (cons find-collects-dir 'collects)
(cons find-user-collects-dir 'user)
(cons find-planet-dir 'planet)))
(define setup-relative-directories
(list (cons find-collects-dir #f)
(cons find-user-collects-dir 'user)
(cons find-planet-dir 'planet)))
(define (path->directory-relative-string
path
#:default [default (if (path? path) (path->string path) path)]
#:dirs [dirs library-relative-directories])
(unless (path-string? path)
(error 'path->directory-relative-string
"expected a path or a string (first argument); got: ~e" path))
(unless (dict? dirs)
(error 'path->directory-relative-string
"expected a dictionary (#:dirs keyword argument); got: ~e" dirs))
(let/ec return
(when (complete-path? path)
(for ([(find-dir dir-name) (in-dict dirs)])
(unless (and (procedure? find-dir)
(procedure-arity-includes? find-dir 0))
(error 'path->directory-relative-string
"expected keys in dictionary to be thunks (~a); got: ~e"
"#:dirs keyword argument"
find-dir))
(let ()
(define-values [ path->relative relative->path ]
(make-relativize find-dir
'relative
'path->relative
'relative->path))
(define exploded
(with-handlers ([exn:fail? (lambda (e) #f)])
(path->relative path)))
(when (list? exploded)
(let* ([relative (path->string
(apply build-path
(map bytes->path-element (cdr exploded))))])
(return
(if dir-name
(format "<~a>/~a" dir-name relative)
(format "~a" relative))))))))
default))