#lang racket/base
(require racket/string)
(require racket/contract)
(provide
(contract-out
[xdgbasedir-data-home (->* () (path-string?) path?)]
[xdgbasedir-config-home (->* () (path-string?) path?)]
[xdgbasedir-cache-home (->* () (path-string?) path?)]
[xdgbasedir-data-dirs (->* () (path-string?) (listof path?))]
[xdgbasedir-config-dirs (->* () (path-string?) (listof path?))]
[xdgbasedir-runtime-dir (->* () (path-string?) (or/c path? boolean?))]))
(define (default var)
(case var
[("XDG_DATA_HOME") (build-path (getenv "HOME") ".local" "share")]
[("XDG_CONFIG_HOME") (build-path (getenv "HOME") ".config")]
[("XDG_CACHE_HOME") (build-path (getenv "HOME") ".cache")]
[("XDG_DATA_DIRS") (list (build-path "/usr" "local" "share")
(build-path "/usr" "share"))]
[("XDG_CONFIG_DIRS") (list (build-path "/etc" "xdg"))]))
(define (string-not-empty? str)
(and str (not (equal? str ""))))
(define (dir var subdir)
(let* ([env-var (getenv var)]
[main-path
(if (string-not-empty? env-var)
env-var
(default var))])
(if (equal? subdir "")
(build-path main-path)
(build-path main-path subdir))))
(define (dirs var subdir)
(let* ([env-var (getenv var)]
[main-paths
(if (string-not-empty? env-var)
(map (λ (path) (build-path path)) (string-split env-var ":"))
(default var))])
(if (equal? subdir "")
main-paths
(map (λ (path) (build-path path subdir)) main-paths))))
(define (xdgbasedir-data-home [subdir ""]) (dir "XDG_DATA_HOME" subdir))
(define (xdgbasedir-config-home [subdir ""]) (dir "XDG_CONFIG_HOME" subdir))
(define (xdgbasedir-cache-home [subdir ""]) (dir "XDG_CACHE_HOME" subdir))
(define (xdgbasedir-data-dirs [subdir ""]) (dirs "XDG_DATA_DIRS" subdir))
(define (xdgbasedir-config-dirs [subdir ""]) (dirs "XDG_CONFIG_DIRS" subdir))
(define (xdgbasedir-runtime-dir [subdir ""])
(if (string-not-empty? (getenv "XDG_RUNTIME_DIR"))
(dir "XDG_RUNTIME_DIR" subdir)
#f))