Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom record reader handler request #2

Closed
FerdiKuehne opened this issue Aug 31, 2018 · 7 comments
Closed

Custom record reader handler request #2

FerdiKuehne opened this issue Aug 31, 2018 · 7 comments

Comments

@FerdiKuehne
Copy link

Good Day Mister!
Currently i write a clojurescript record serialization for fressian.

I already implemented custom write-handlers with the help of your fress library.
Now i'm stuck with custom read handlers. It would be great if it is possible to override the default record reader like the record write-handler.

Sincerely Ferdi!

@pkpkpk
Copy link
Owner

pkpkpk commented Aug 31, 2018

Try master. should be fn<rdr,tag, field-count,name->map-ctor>

@pkpkpk
Copy link
Owner

pkpkpk commented Aug 31, 2018

can probably get rid of the name->map-ctor arg

@FerdiKuehne
Copy link
Author

yeah without name->map-ctor arg would be awesome. And also if the record is not match could it be possible to return an custom object like your taggedObject?

@pkpkpk
Copy link
Owner

pkpkpk commented Aug 31, 2018

Can you explain your use case alittle bit for me? Are you trying to instantiate stuff before calling the record constructor? If so it may be better to read/write as custom types rather than records

@FerdiKuehne
Copy link
Author

Good morning!
Sorry for the delayed response.
Best way to explain the case is with the following code:

  (defrecord IncognitoTaggedLiteral [tag value])

  (defn incognito-write-handlers [write-handlers]
    {"record" (fn [w rec]
                (let [{:keys [tag] :as r} (if (isa? (type rec) incognito.base.IncognitoTaggedLiteral)
                                            (into {} rec)
                                            (incognito-writer @write-handlers rec))]
                  (write-tag w "record" 2)
                  (write-object w (str tag))
                  (write-tag w "map" 1)
                  (beginClosedList w)
                  (doseq [[field value] r]
                    (write-object w field true)
                    (write-object w value))
                  (endList w)))})

  (defn incognito-reader [read-handlers m]
    (if (read-handlers (:tag m))
      ((read-handlers (:tag m)) (:value m))
      (map->IncognitoTaggedLiteral m)))

  (defn incognito-read-handlers [read-handlers]
    {"record" (fn [rdr tag _]
                (let [tag   (read-object rdr)
                      value (read-object rdr)]
                  (incognito-reader @read-handlers
                                    {:tag tag :value val})))})

  (defrecord SomeRecord [f1 f2])
  (def rec (SomeRecord. "field1" "field2"))
  (def buf (fress.api/byte-stream))
  (def writer (fress.api/create-writer buf :handlers (incognito-write-handlers (atom {'incognito.fressian.SomeRecord (fn [foo] (println "foos") (assoc foo :c "donkey"))}))))
  (fress.api/write-object writer rec)
  (fress.api/read buf :handlers (incognito-read-handlers (atom {})))
  ;read returns  => #fress.reader.TaggedObject{:tag "record", :value #js ["incognito.fressian/SomeRecord" {:value {:f1 "field1", :c "donkey", :f2 "field2"}, :tag incognito.fressian/SomeRecord}]}


  ;it should return => #incognito.base.IncognitoTaggedLiteral{:tag incognito.fressian/SomeRecord, :value {:f1 "field1", :c "donkey", :f2 "field2"}}

The custom read-handler for "record" is somehow ignored. Sorry for the confusion. I hope the answer can help.

Best Regards F

@pkpkpk
Copy link
Owner

pkpkpk commented Sep 3, 2018

I had it set to look for :record, you are right it should have been a string

@FerdiKuehne
Copy link
Author

Big thanks! Well done!
It's working! I think the issue can be closed.

Best Regards F

@pkpkpk pkpkpk closed this as completed Sep 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants