/
options.clj
44 lines (39 loc) · 1.5 KB
/
options.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
(ns datasplash.options
(:require [clojure.string :as str]))
(def the-void Void/TYPE)
(defn extract-default-type
[klass]
(-> klass
(.getName)
(str/split #"\.")
(last)))
(def annotations-mapping
{:default (fn [{:keys [type]}] (symbol (str "org.apache.beam.sdk.options.Default$" (extract-default-type type))))
:description 'org.apache.beam.sdk.options.Description
:hidden 'org.apache.beam.sdk.options.Hidden})
(defn capitalize-first
[s]
(str (.toUpperCase (subs s 0 1))
(subs s 1)))
(defmacro defoptions
[interface-name specs]
`(do
(gen-interface
:name ~interface-name
:extends [org.apache.beam.sdk.options.PipelineOptions]
:methods
[~@(apply concat
(for [[kw {:keys [type] :as spec}] specs
:let [nam (capitalize-first (name kw))
annotations (select-keys spec [:default :description :hidden])]]
`([~(with-meta
(symbol (str "get" nam))
(reduce (fn [acc [k v]]
(assoc acc
(let [m (get annotations-mapping k)]
(if (fn? m) (m spec) m))
(if (nil? v) true v)))
{} annotations))
[] ~type]
[~(with-meta (symbol (str "set" nam)) `{}) [~type] ~the-void])))])
(def ~interface-name '~interface-name)))