Hi,

I am wiring up a bunch of CRUD command handlers for different aggregates 
using prismatic schema to validate and it is screaming out for a macro, but 
my ignorance is screaming even louder :).

The form I want to emit is something like (for a 'Location' for example):

(s/defn ^:always-validate create :- [events/LocationDefinedSchema]
  [detail :- (-> commands/DefineLocationSchema :detail)]
  (let [ar (common/new-ar detail)
        event (events/event :location-defined ar)]
    [event]))


Where 'events/LocationDefinedSchema' and 'commands/DefineLocationSchema' 
are prismatic schemas.

To make it generic (and relying on convention) then once I have the 
aggregate I can do:

(def aggregate :location)

(def DefineCommandSchema (symbol (str "my.domain.commands/Define" 
(clojure.string/capitalize (name aggregate)) "Schema")))

(def DefinedEventSchema (symbol (str "my.domain.events/" 
(clojure.string/capitalize (name aggregate)) "DefinedSchema")))
(def defined-event-key (keyword (str (name aggregate) "-defined")))
(def define-command-key (keyword (str "define-" (name aggregate))))


which allows the generic create form to be:

(s/defn ^:always-validate create :- [DefinedEventSchema]
  [detail :- (-> DefineCommandSchema :detail)]
  (let [ar (common/new-ar detail)
        event (events/event defined-event-key ar)]
    [event]))


I then tried to extract this into a macro:

(defmacro create-infrastructure

  [aggregate]
  (let [{:keys [define-command-schema
                defined-event-schema
                define-command-key
                defined-event-key]} (default-options aggregate)]

    `(do
       (schema.core/defn ^:always-validate create :-
                            [~defined-event-schema]
         [detail# :- (:detail ~define-command-schema)]
         (let [ar# (common/new-ar detail#)
               event# (events/event ~defined-event-key ar#)]
           [event#])))

    ))


Where 'default-options' just returns a map with the specified keys and 
constructs some symbols.

Unfortunately the emitted form is:

(macroexpand-1 '(create-infrastructure :location))
=> (do 
  (schema.core/defn my.domain.internal.support.crud-handler/create :- 
[my.domain.events/LocationDefinedSchema] [detail__10635__auto__ :- 
(:detail my domain.commands/DefineLocationSchema)] (clojure.core/let 
[ar__10636__auto__ (my.domain.internal.model.common/new-ar 
detail__10635__auto__) event__10637__auto__ (my.domain.events/event 
:location-defined ar__10636__auto__)] [event__10637__auto__])))

This works somewhat but it is missing the '^:always-validate' and I have 
tried to use (with-meta) but it just doesn't to do what I want.

Any suggestions on getting the meta to pass through or thoughts on this 
macro in general are greatly appreciated!

Thanks!

----

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to