clojusc / protobuf

A Clojure interface to Google's protocol buffers
https://clojusc.github.io/protobuf/
Eclipse Public License 1.0
73 stars 8 forks source link

tricky on handle to encode/decode on Any #39

Open netpyoung opened 5 years ago

netpyoung commented 5 years ago

I want to put some message to Any. but the problem occurs.

let me assume. we have that kind of message.

message A {
   Any any;
}

messsage B {
   int b;
}

So I can writing small encode/decode part for B

(let [message-b {:b 10}
      encoded (->> (protobuf/create B message-b)
                   (protobuf/->bytes)
                   (assoc {} :value)
                   (protobuf/create Any))
      decoded (->> encoded
                   :value
                   (protobuf/bytes-> (protobuf/create B))
                   (into {}))]
  (= message-b decoded))

but When I combine A with B . there is some tricky problem.

(let [message-b {:b 10}
      encoded (->> (protobuf/create B message-b)
                   (protobuf/->bytes)
                   (assoc {} :value)
                   (protobuf/create Any)
                   (assoc {} :any)
                   (protobuf/create A)
                   (protobuf/->bytes))

      decoded (->> encoded
                   (protobuf/bytes-> (protobuf/create A))
                   :any
                   (protobuf/create A)
                   :value
                   ;; at this point. value's type is bytestring so It need to call `.toByteArray`
                   (.toByteArray)       ; <<< a little tricky
                   (protobuf/bytes-> (protobuf/create B))
                   (into {}))]
  (= message-b decoded))

So I need to fix encode/decode part like that.

(let [message-b {:b 10}
      encoded (->> (protobuf/create B message-b)
                   (protobuf/->bytes)
                   ;; I inserted toByteArray on decoder. but it's type is `byte[]`
                   (com.google.protobuf.ByteString/copyFrom) ;; So It need to convert to bytestring.
                   (assoc {} :value)
                   (protobuf/create Any))
      decoded (->> encoded
                   :value
                   (.toByteArray) ;; so I inserted.
                   (protobuf/bytes-> (protobuf/create B))
                   (into {}))]
  (= message-b decoded))

It's works. but com.google.protobuf.ByteString/copyFrom on this code likes tricky skill. Is any other good suggestion of this? or Is anything what i missed?