On Monday, August 19, 2019 at 3:35:00 PM UTC-4, Brian Adkins wrote:
>
> I'm working on a macro to allow the following:
>
> (routes
>  ("/foo" foo-handler #:method put)
>  ("/bar" bar-handler #:methods (put update))
>  ("/baz" baz-handler))
>
> The idea is that you could restrict a route based on the HTTP method 
> either for one method using #:method or for a list of methods using 
> #:methods. I tried using some ideas from the following examples:
>
> https://docs.racket-lang.org/syntax/Optional_Keyword_Arguments.html
>
> https://docs.racket-lang.org/syntax/More_Keyword_Arguments.html
>
> The attempt below does not work, and from my debugging I think it's 
> probably the wrong approach. If there are examples of this sort of thing, 
> I'd love to see them.
>
> Thanks,
> Brian Adkins
>
> (define-syntax (routes stx)
>   (syntax-parse stx
>     [ (routes (route:string
>                handler:id
>                (~alt (~optional (~or* (~seq #:methods (methods:expr ...))
>                                       (~seq #:method method:expr))
>                                 #:name "#:method, or #:methods option")
>                      (~optional (~seq #:when guard:expr)
>                                 #:name "#:when option"))
>                ...)
>               ...)
>       (with-syntax ([ name  (format-id stx "axio-routes") ])
>         #'(define name (list (list route handler 'method (list 'methods 
> ...)) ...)))]))
>
>
The following got me over the main hurdle:

(define-syntax (routes stx)
  (syntax-parse stx
    [ (routes (element ...) ...)
      (with-syntax ([ name  (format-id stx "axio-routes") ])
        #'(define name (list (route-element element ...) ...)))]))

(define-syntax (route-element stx)
  (syntax-parse stx
    [ (route-element route:string
                     handler:id
                     (~alt (~optional (~or* (~seq #:methods (methods:expr 
...))
                                            (~seq #:method method:expr))
                                      #:name "#:method, or #:methods 
option")
                           (~optional (~seq #:when guard:expr)
                                      #:name "#:when option"))
                     ...)
      (with-syntax ([ m  (or (attribute method)  #'#f) ]
                    [ ms (or (attribute methods) #'#f) ])
        #'(list route handler 'm 'ms))]))

(routes
 ("/foo" foo-handler #:method put)
 ("/bar" bar-handler #:methods (put update))
 ("/baz" baz-handler))

axio-routes

==> '(("/foo" #<procedure:foo-handler> put #f) ("/bar" 
#<procedure:bar-handler> #f (put update)) ("/baz" #<procedure:baz-handler> 
#f #f))

Now I just need to normalize to a list of HTTP methods vs. having separate 
fields. 

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/0e3bd33f-9666-4f3f-800e-1ccd7f6a2dee%40googlegroups.com.

Reply via email to