Skip to content

Instantly share code, notes, and snippets.

@kawas44
Last active February 8, 2022 09:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kawas44/5f079709ff9bcd49521c4ab699689661 to your computer and use it in GitHub Desktop.
Save kawas44/5f079709ff9bcd49521c4ab699689661 to your computer and use it in GitHub Desktop.
Clj var-args helpers
;;;; Varargs helpers
(defn- simple-name
[s]
(if-let [idx (str/index-of s \$)] (subs s (inc idx)) s))
(defn- helper-name
[cls]
(-> (simple-name cls)
(str/replace #"([a-z0-9])([A-Z]+)" "$1-$2")
(str/lower-case)
(str "-arr")
(symbol)))
(defn- vargs-specs
[specs]
(apply concat
(for [[package & clss] specs]
(map #(vector package % (helper-name (str %))) clss))))
(defn- add-array-type-hint
[sym package cls]
(vary-meta sym assoc :tag (format "[L%s.%s;" package cls)))
(defn- helper-define
[vargs-spec]
(let [[pkg cls fname] vargs-spec]
`(defn ~(add-array-type-hint fname pkg cls)
~(str "Returns a Java array of " cls)
([] (make-array ~cls 0))
([~'coll] (into-array ~cls ~'coll)))))
(defmacro defhelpers
"Define & type hint functions to create array of target objects.
Example:
`(defhelpers
(:classe (com.foo SQLToken Foo$Field)
(com.bar JobOpt))`
Will define functions `sqltoken-arr`, `field-arr` and `job-opt-arr`.
Helper functions have two arities:
- [] create an empty array properly type hinted
- [coll] create an array from coll properly type hinted
"
[classes-specs]
(let [va-specs (vargs-specs (next classes-specs))]
`(do ~@(map helper-define va-specs) nil)))
;; Usage
;; (vargs/defhelpers
;; (:classes
;; (com.google.cloud.bigquery BigQuery$TableOption
;; BigQuery$JobOption)
;; (com.google.cloud RetryOption)))
;; You will be able to use a function like `table-option-arr` like this:
;; (table-option-arr) => Make an empty Java array of BigQuery$TableOption
;; (table-option-arr coll) => Make a Java array of a collection of BigQuery$TableOption
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment