(m/rewrite {:items [{:a 10 :b 20 :c 55}
{:a 30 :b 40 :c 45}]}
{:items [{:a !alpha :b !beta} ...]}
{:items [{:alpha !alpha :b !beta} ...]})@jimmy thank you!
As part of a larger transform, Iām trying to handle parameters that follow this pattern, i.e., they can either express simple operations to apply to a set, or they can express the desired value of the set:
;; owners current state: [3 4 5]
{:owners {:add [1 2] :remove [3 4]}} ;; => {:owner_ids [1 2 5]}
{:owners {:reset [1 2]}} ;; => {:owner_ids [1 2]}
Right now Iām doing the actual application of the add/remove operations in Clojure code in the RHS of a match:
(m/match
{:ctx {:db db}
:attributes {:id 123
:input {:owners {:add [1 2] :remove [3 4]}}}}
{:ctx {:db ?db :as ?ctx}
:attributes {:id ?id
:input {:owners ?owner-ops}}}
{:ctx ?ctx
:attributes {:id ?id
:input {:owner_ids (apply-ops
(get-current-owners ?db ?id)
?owner-ops)}}})
Is there a more idiomatic way to do this that expresses more of the transformation in Meander?That looks good to me. Pretty easy to follow.
In terms of idioms, I would say just try to balance what Meander and "vanilla" Clojure are good at. For example, it is totally possible to apply the owner operations you have here using m/rewrite but, apart from being a good exercise, it may confuse people on your team, etc.
I have this rewrite where Iām using m/app to slightly post-process the output. In the case of !description I would like to keep the original value as well as the post-processed one, but mentioning it twice in the output means that 2 descriptions are consumed per :invoice/item. Is there a way to overcome this?
(defn xero-invoice->datom [invoice & {:keys [service/provider]}]
(m/rewrite
(assoc invoice ::provider provider)
{::provider ?provider
:Invoices
[{:LineItems [{:UnitAmount !unit-amount
:LineAmount !line-amount
:Description !description
:Quantity !quantity}
...]
:CurrencyCode ?currency
:InvoiceNumber ?invoice-id
:DateString ?issue-date
:Total ?amount
:DueDateString ?due-date
:InvoiceID ?xero-id
:TotalTax ?vat
:Contact {:Name ?xero-contact-name}}]}
{:service/provider ?provider
:service/consumer (m/app names->consumers ?xero-contact-name)
:time/issue-date (m/app instant/read-instant-timestamp ?issue-date)
:time/due-date (m/app instant/read-instant-timestamp ?due-date)
:payment/amount ?amount
:payment/currency (m/app currency ?currency)
:payment/vat ?vat
:xero/id ?xero-id
:invoice/id ?invoice-id
:invoice/items [{:person/consultant (m/app desc->consultant !description)
:xero/description !description
:service/quantity !quantity
:service/unit :hours
:payment/amount !line-amount}
...]}))