Last active
February 20, 2020 06:15
-
-
Save hkupty/783a89820fdc10d9a525cdf7cd2abac2 to your computer and use it in GitHub Desktop.
Transforming java proto instances in clojure maps
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;; The main function is `protobuf->map`, which performs the transformation. | |
| ;; Runtime reflection can be avoided if class is known beforehand. | |
| ;; The macro is completely optional, though it makes things *slightly* easier to read: | |
| ;; (protobuf->clj instance OuterClass$InnerClass) vs (protobuf->map instance (OuterClass$InnerClass/getDescriptor)) | |
| (defn- *proto->fields | |
| "Get fields from protobuf object's descriptor as clojure keywords" | |
| [descr] | |
| (map #(keyword (.getName %)) | |
| (.getFields descr))) | |
| (defn protobuf->map | |
| "Returns a map representation of the proto object. | |
| Single-arity version will perform reflection to get fields" | |
| ([proto-obj] | |
| (protobuf->map proto-obj | |
| (.invoke | |
| (.getMethod (.getClass proto-obj) | |
| "getDescriptor" | |
| (into-array Class [])) | |
| nil | |
| (into-array Object [])))) | |
| ([proto-obj descr] | |
| (let [b (bean proto-obj)] | |
| (select-keys b | |
| (*proto->fields descr))))) | |
| (defmacro protobuf->clj | |
| "Provides syntactic sugar to avoid runtime reflections if class is known." | |
| [object clazz] | |
| `(protobuf->map ~object (~(symbol (name clazz) "getDescriptor")))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment