hello friends, I am working on the POC
I need some help
I don’t see how I can go from input
-> spec
which validate input ->
then we generate the operation
but how can we manage to call all the ser*
from the input
for example, let’s take this operation from lambda
{"TagResource"
{"name" "TagResource",
"http"
{"method" "POST",
"requestUri" "/2017-03-31/tags/{ARN}",
"responseCode" 204},
"input" {"shape" "TagResourceRequest"},
"errors"
[{"shape" "ServiceException"}
{"shape" "ResourceNotFoundException"}
{"shape" "InvalidParameterValueException"}
{"shape" "TooManyRequestsException"}]}}
from this operation we generate specs
for every shape like before
then the gen-operation
makes the defn
& fspec
the idea is to split spec
from ser
& deser
so we map into a sets all input-roots
and inputs
shape
now, once spec validate my TagResourceRequest
how can I pass all the ser
function ?
"TagResourceRequest"
{"type" "structure",
"required" ["Resource" "Tags"],
"members"
{"Resource"
{"shape" "FunctionArn", "location" "uri", "locationName" "ARN"},
"Tags" {"shape" "Tags"}}}
which should be an entry map like that
{:resource “some string” :tags “some tags type”}
SPAM alert
So I’ve been working today on this problem and here is some code that might go in the right direction (help me god)
(defn shape-name->ser-name
"Given a shape name, transorm it to a ser-* name."
[shape-name]
(->> shape-name (str "ser-") portkey.aws/dashed symbol))
(defmulti gen-ser-input (fn [shape-name api _]
[(get-in api ["metadata" "protocol"]) (get-in api ["shapes" shape-name "type"])]))
(defmethod gen-ser-input :default [shape-name api _]
(let [mess [(get-in api ["metadata" "protocol"]) (get-in api ["shapes" shape-name "type"])]]
(throw
(ex-info (str "unsupported protocol/type for shape : " shape-name)
{:shape mess}))))
(defmethod gen-ser-input ["rest-json" "integer"] [shape-name api input] input)
(defmethod gen-ser-input ["rest-json" "structure"] [shape-name api input]
(let [shape (get-in api ["shapes" shape-name])
keep-keys-args (into {}
(mapcat #(vec [[(-> % portkey.aws/dashed keyword) %]]))
(keys (shape "members")))]
`(let [vv-fn# ~(into {}
(map (fn [[k# v#]]
[k# (shape-name->ser-name (v# "shape"))]))
(shape "members"))]
(into {}
(comp (keep (fn [[k# v#]] (when-some [k# (~keep-keys-args k#)] [k# v#])))
(map (fn [[k# v#]]
(let [ser-fn# (vv-fn# k#)]
[k# (ser-fn# v#)]))))
~input))))
(defmethod gen-ser-input ["rest-json" "string"] [shape-name api input]
(let [{:strs [enum] :as shape} (get-in api ["shapes" shape-name])]
(if enum
`(let [m# ~(into {} (mapcat #(vector [% %] [(-> % aws/dashed keyword) %])) enum)]
(m# input))
input)))
(defmethod gen-ser-input ["rest-json" "map"] [shape-name api input] input)
(defmethod gen-ser-input ["rest-json" "boolean"] [shape-name api input] input)
(defmethod gen-ser-input ["rest-json" "timestamp"] [shape-name api input] input)
(defmethod gen-ser-input ["rest-json" "list"] [shape-name api input] input)
(defmethod gen-ser-input ["rest-json" "blob"] [shape-name api input]
`(aws/base64-encode ~input))
(defn ser-fn-fn
"Fonction tu lui donne un input et il t'appelle les fn de ser qui
on été généré pour faire le confirming."
[input]
{})
(let [{:keys [inputs]} (shapes-by-usage api)
f (fn [shape-name api]
(let [varname (shape-name->ser-name shape-name)
input# (symbol "shape-input")]
`(defn ~varname
[~input#]
~(gen-ser-input shape-name api input#))))]
(map (fn [in]
(f in api))
inputs))
which generate stuff like that =>
(clojure.core/defn
ser-reserved-concurrent-executions
[shape-input]
shape-input)
(clojure.core/defn
ser-tracing-config
[shape-input]
(clojure.core/let
[vv-fn__53839__auto__ {“Mode” ser-tracing-mode}]
(clojure.core/into
{}
(clojure.core/comp
(clojure.core/keep
(clojure.core/fn
[[k__53840__auto__ v__53841__auto__]]
(clojure.core/when-some
[k__53840__auto__ ({:mode “Mode”} k__53840__auto__)]
[k__53840__auto__ v__53841__auto__])))
(clojure.core/map
(clojure.core/fn
[[k__53840__auto__ v__53841__auto__]]
(clojure.core/let
[ser-fn__53842__auto__
(vv-fn__53839__auto__ k__53840__auto__)]
[k__53840__auto__
(ser-fn__53842__auto__ v__53841__auto__)]))))
shape-input)))
What I’ve done is to rebase wip
stuff on master
then I generate defn fors ser-*
I think I now understand the purpose of the resp
but I think one fn should do the trick for each protocol