processone / xmpp

Erlang/Elixir XMPP parsing and serialization library on top of Fast XML

Home Page:http://process-one.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to decode with var

grizzly-monkey opened this issue · comments

commented

Hello i want to write a custom spec in xmpp_codec.spec which will decode json cdata

_-xml(sync,
#elem{name = <<"sync">>,
xmlns = <<"mycustom:xmlsns:sync">>,
cdata = #cdata{label = '$json',
dec = {jsonutil,dec_json, []}, ### how to pass the attribute variable here
enc = {jsonutil,enc_json, []}}, ### how to pass the attribute variable here
result = {sync, '$c','$json', '$els'},
attrs = [ #attr{name = <<"c">>,
default = 0}
]}).

in dec = dec_json , [] i want to pass the label '$c' so that my decode will be based on '$c'

how can i achieve this right now it just accepts the atom or constants is it possible to pass a attribute var ?
any other method i can achieve this?

Merci

Conditional decoding is unsupported. I was thinking about it, but it's not that simple and may introduce infinite loops.

Also, 'default = 0' is incorrect, you need to add dec/enc functions in this case.

It seems like you need something like this:

-xml(sync,
     #elem{name = <<"sync">>,
           xmlns = <<"mycustom:xmlsns:sync">>,
           result = {sync, '$c','$json', '$_els'},
           cdata = #cdata{label = '$json'},
           attrs = [#attr{name = <<"c">>,
                          enc = {enc_int, []},
                          dec = {dec_int, [0, unlimited]},
                          default = 0}]}).

Then in ejabberd's code you should add json decoding/encoding of #sync.json based on #sync.c value.

commented

yes zinid you are correct i need
enc = {enc_int, []},
dec = {dec_int, [0, unlimited]},

however my json decoding should happen based on my attribute <<"c">> is there any other way you could point me to and i can try it

No, you should make decoding manually in the code, as I said above. E.g.

foo(#sync{c = C, json = Data}) when C == 0 ->
    try jiffy:decode(Data) of
       JSON -> do_something(JSON)
    catch _:_ ->
          process_invalid_json()
    end;
...

I actually need this conditional decoding myself in some places (like privacy lists decoding), but implementing this is tough.

commented

Cool thanks hope we can get this conditional decoding ... :) thanks for your help 👍