File: insta.rkt

package info (click to toggle)
racket 6.7-3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 97,344 kB
  • ctags: 39,484
  • sloc: ansic: 277,847; sh: 33,512; asm: 13,558; lisp: 7,113; cpp: 2,872; makefile: 2,421; pascal: 2,262; exp: 499; python: 274; xml: 11
file content (68 lines) | stat: -rw-r--r-- 2,480 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#lang racket
(require web-server/servlet
         web-server/servlet-env
         (for-syntax racket)
         (for-syntax syntax/kerncase))

(provide 
 (all-from-out web-server/servlet)
 (except-out (all-from-out racket) #%module-begin)
 (rename-out [web-module-begin #%module-begin]))

(define extra-files-path #f)
(define launch-browser? #t)

(provide/contract
 [static-files-path (path-string? . -> . void?)])
(define (static-files-path path)
  (set! extra-files-path path))

(provide/contract
 [no-web-browser (-> void)])
(define (no-web-browser)
  (set! launch-browser? false))

;; check-for-def : syntax syntax-list -> void
;; Expands body-stxs and determines if id-stx is bound therein.
;; If not error w/ error-msg. stx is the root syntax context for everything
(define-for-syntax (check-for-def stx id-stx error-msg body-stxs)
  (with-syntax ([(pmb body ...)
                 (local-expand 
                  (quasisyntax/loc stx
                    (#%module-begin #,@body-stxs))
                  'module-begin 
                  empty)])
    (let loop ([syns (syntax->list #'(body ...))])
      (if (empty? syns)
          (raise-syntax-error 'insta error-msg stx)
          (kernel-syntax-case (first syns) #t
            [(define-values (id ...) expr)
             (unless
                 (ormap (lambda (id)
                          (and (identifier? id)
                               (free-identifier=? id id-stx)))
                        (syntax->list #'(id ...)))
               (loop (rest syns)))
             ]
            [_
             (loop (rest syns))])))
    (quasisyntax/loc stx
      (pmb body ...))))

(define-syntax (web-module-begin stx)
  (syntax-case stx ()
    [(_ body ...)
     (let* ([start (datum->syntax stx 'start)]
            [expanded (check-for-def stx 
                                     start "You must provide a 'start' request handler."
                                     #'(body ...))])
       (quasisyntax/loc stx
         (#,@expanded
          (provide/contract (#,start (request? . -> . can-be-response?)))
          (serve/servlet (contract (request? . -> . can-be-response?) #,start
                                   'you 'web-server
                                   "start"
                                   #f)
                         #:port 0
                         #:extra-files-paths (if extra-files-path (list extra-files-path) empty)
                         #:launch-browser? launch-browser?))))]))