[racket] Splicing nested syntax clauses
Here's another approach:
#lang racket/base
(require (for-syntax racket/base)
web-server/dispatch)
(begin-for-syntax
(define-syntax-rule (in-stx-list l)
(in-list (syntax->list l))))
(define-syntax (nested-dispatch-rules stx)
(syntax-case stx ()
[(_ [(prefix ...) [(suffix ...) handler] ...] ...)
(with-syntax
([((clause ...) ...)
(for/list ([pre (in-stx-list #'((prefix ...) ...))]
[post (in-stx-list #'(([(suffix ...) handler] ...) ...))])
(with-syntax
([(prefix ...) pre]
[([(suffix ...) handler] ...) post])
#'([(prefix ... suffix ...) handler] ...)))])
(syntax/loc stx
(dispatch-rules clause ... ...)))]))
(module+ test
(define (handler-a req x) "A")
(define (handler-b req x) "B")
(define (handler-c req x) "C")
(define (handler-d req x) "D")
(define-values (dispatch dispatch-url)
(nested-dispatch-rules
[("page-a")
[("handler-a" (integer-arg)) handler-a]
[("handler-b" (integer-arg)) handler-b]]
[("page-b")
[("handler-c" (integer-arg)) handler-c]
[("handler-d" (integer-arg)) handler-d]]))
(require rackunit)
(check-equal? (dispatch-url handler-a 0) "/page-a/handler-a/0")
(check-equal? (dispatch-url handler-b 1) "/page-a/handler-b/1")
(check-equal? (dispatch-url handler-c 2) "/page-b/handler-c/2")
(check-equal? (dispatch-url handler-d 3) "/page-b/handler-d/3"))
On Fri, Jun 27, 2014 at 1:47 PM, Jack Firth <jackhfirth at gmail.com> wrote:
> I'm working with some servlet dispatching code and I want to be able to use
> dispatch-rules to generate the url to response mappings, but I want to be
> able to group related handlers to subpages. Under dispatch-rules, that looks
> something like this:
>
> (dispatch-rules
> [("page-a" "handler-a" (integer-arg)) handler-a]
> [("page-a" "handler-b" (integer-arg)) handler-b]
> [("page-b" "handler-c" (integer-arg)) handler-c]
> [("page-b" "handler-d" (integer-arg)) handler-d])
>
> What I want is to be able to specify a tree structure of some sort like
> this:
>
> (my-dispatch-rules
> [(my-dispatch-rules "page-a"
> [("handler-a" (integer-arg)) handler-a)]
> [("handler-b" (integer-arg)) handler-b)]
> [(my-dispatch-rules "page-b"
> [("handler-c" (integer-arg)) handler-c)]
> [("handler-d" (integer-arg)) handler-d)])
>
> And have that expand, placing the page-a and page-b bits in the appropriate
> areas. From what I understand of macros, the appropriate way to do this is
> with quasiquoting and splicing unquotes, but I can't seem to figure out
> using splicing with syntax-case, and the various tutorials and documentation
> I've looked at haven't helped me really wrap my head around the specifics.
> If someone could point me towards enlightenment, that would be much
> appreciated.
>
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users
>
--
Jay McCarthy
http://jeapostrophe.github.io
"Wherefore, be not weary in well-doing,
for ye are laying the foundation of a great work.
And out of small things proceedeth that which is great."
- D&C 64:33