File 8321-asn1-Use-the-new-json-module-for-the-JER-backend.patch of Package erlang

From 7e004ed7b002eb95ea217b191de3074175e5253d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Fri, 8 Mar 2024 08:01:55 +0100
Subject: [PATCH] asn1: Use the new `json` module for the JER backend

---
 lib/asn1/src/asn1ct.erl      | 16 +++++++---------
 lib/asn1/src/asn1ct_gen.erl  | 30 +++++-------------------------
 lib/asn1/src/asn1rtt_jer.erl | 18 ++++++++----------
 3 files changed, 20 insertions(+), 44 deletions(-)

diff --git a/lib/asn1/doc/src/asn1ct.xml b/lib/asn1/doc/src/asn1ct.xml
index 96b2ea6629..69bd72e69b 100644
--- a/lib/asn1/doc/src/asn1ct.xml
+++ b/lib/asn1/doc/src/asn1ct.xml
@@ -147,25 +147,14 @@ File3.asn</pre>
 	      <c>jer_encode(Type, Value)</c> and <c>jer_decode(Type, Bytes)</c>.
 	    </p>
 	    <p>
-	      The <c>jer</c> encoding rules (ITU-T X.697) are experimental in
-	      OTP 22.
-	      There is support for a subset of the X.697 standard, for example there is no support for:
+	      JER (ITU-T X.697) are experimental in OTP 22. There is support for a
+	      subset of the X.697 standard, for example there is no support for:
 	    </p>
 	    <list>
 	      <item>JER encoding instructions</item>
 	      <item>the REAL type</item>
 	    </list>
 	    <p>
-	      Also note that when using the <c>jer</c> encoding rules the
-	      generated module will get a dependency to an external json
-	      component. The generated code is currently tested together with:
-	    </p>
-	    <list>
-	      <item><c>jsx</c> which currently is the default.</item>
-	      <item><c>jsone</c> can be chosen instead of <c>jsx</c>
-	      by providing the option <c>{d,jsone}</c>.</item>
-	    </list>
-	    <p>
 	      If the encoding rule option is omitted, <c>ber</c> 
 	      is the default.
 	    </p>
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index bf242bbc73..e69c63f847 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -765,7 +765,7 @@ pgen_dispatcher(Gen, Types) ->
 	       #gen{erule=ber} ->
 		   "iolist_to_binary(element(1, encode_disp(Type, Data)))";
                #gen{erule=jer} ->
-                   ["?JSON_ENCODE(",{call,jer,encode_jer,[CurrMod,"Type","Data"]},")"];
+                   [{call,jer,encode_jer,[CurrMod,"Type","Data"]}];
 	       #gen{erule=per,aligned=false} when NoFinalPadding ->
 		   asn1ct_func:need({uper,complete_NFP,1}),
 		   "complete_NFP(encode_disp(Type, Data))";
@@ -789,7 +789,7 @@ pgen_dispatcher(Gen, Types) ->
     case Gen#gen.jer of
         true ->
             emit(["jer_encode(Type, Data) ->",nl]),
-            JerCall = ["?JSON_ENCODE(",{call,jer,encode_jer,[CurrMod,"Type","Data"]},")"],
+            JerCall = [{call,jer,encode_jer,[CurrMod,"Type","Data"]}],
             case NoOkWrapper of
                 true ->
                     emit(["  ",JerCall,"."]);
@@ -827,7 +827,7 @@ pgen_dispatcher(Gen, Types) ->
 		emit(["   {Data,Rest} = ber_decode_nif(Data0),",nl]),
 		"Data";
 	    {#gen{erule=jer},false} ->
-		"?JSON_DECODE(Data)";
+		"json:decode(Data)";
 	    {#gen{erule=jer},true} ->
 		exit("JER + return rest not supported");
 	    {_,_} ->
@@ -869,7 +869,7 @@ pgen_dispatcher(Gen, Types) ->
                 false -> emit(["try",nl]);
                 true -> ok
             end,
-            JerDecWrap = "?JSON_DECODE(Data)",
+            JerDecWrap = "json:decode(Data)",
 	    emit(["   Result = ",
                   {call,jer,
                    decode_jer,
@@ -1349,27 +1349,7 @@ gen_head(#gen{options=Options}=Gen, Mod, Hrl) ->
          end,
     emit(["-asn1_info([{vsn,'",asn1ct:vsn(),"'},",nl,
 	  "            {module,'",Mod,"'},",nl,
-	  "            {options,",io_lib:format("~p",[Options1]),"}]).",nl,nl]),
-    JerDefines = case Gen of
-                     #gen{erule=jer} ->
-                         true;
-                     #gen{jer=true} ->
-                         true;
-                     _ ->
-                         false
-                 end,
-    JerDefines andalso 
-%% FIXME add jiffy as well and maybe a third argument where the user
-%% can provide the JSON encode/decode as a fun (or atom).
-        emit([
-              "-ifdef(jsone).",nl,
-              "-define(JSON_DECODE(Data),jsone:decode(Data)).",nl,
-              "-define(JSON_ENCODE(Term),jsone:encode(Term)).",nl,
-              "-else.",nl,
-              "-define(JSON_DECODE(Data),jsx:decode(Data,[return_maps])).",nl,
-              "-define(JSON_ENCODE(Term),jsx:encode(Term)).",nl,
-              "-endif.",nl
-             ]).
+	  "            {options,",io_lib:format("~p",[Options1]),"}]).",nl,nl]).
 
 gen_hrlhead(Mod) ->
     emit(["%% Generated by the Erlang ASN.1 compiler. Version: ",
diff --git a/lib/asn1/src/asn1rtt_jer.erl b/lib/asn1/src/asn1rtt_jer.erl
index 3e0f2d835f..6fdf0390a2 100644
--- a/lib/asn1/src/asn1rtt_jer.erl
+++ b/lib/asn1/src/asn1rtt_jer.erl
@@ -33,7 +33,8 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 encode_jer(Module, Type, Val) ->
     Info = Module:typeinfo(Type),
-    encode_jer(Info, Val).
+    Enc = encode_jer(Info, Val),
+    iolist_to_binary(json:encode(Enc)).
 
 %% {sequence,
 %%    Name::atom() % The record name used for the sequence 
@@ -171,7 +172,9 @@ encode_jer_component_tab([{Name, Type, _OptOrDefault} | CompInfos], [Value | Res
     encode_jer_component_tab(CompInfos, Rest, Simple, MapAcc#{Name => Enc});
 encode_jer_component_tab([], _, _Simple, MapAcc) ->
     MapAcc.
-encode_jer_component_map([{Name, AName, Type, _OptOrDefault} | CompInfos], MapVal, Acc) when is_map_key(AName,MapVal)->
+
+encode_jer_component_map([{Name, AName, Type, _OptOrDefault} | CompInfos], MapVal, Acc)
+  when is_map_key(AName, MapVal)->
     Value = maps:get(AName, MapVal),
     Enc = encode_jer(Type, Value),
     encode_jer_component_map(CompInfos, MapVal, [{Name,Enc}|Acc]);
@@ -179,15 +182,12 @@ encode_jer_component_map([{_Name, _AName, _Type, 'OPTIONAL'} | CompInfos], MapVa
     encode_jer_component_map(CompInfos, MapVal, Acc);
 encode_jer_component_map([{_Name, _AName, _Type, {'DEFAULT',_}} | CompInfos], MapVal, Acc) ->
     encode_jer_component_map(CompInfos, MapVal, Acc);
-encode_jer_component_map([], MapVal, []) when map_size(MapVal) == 0->
-    #{}; % ensure that it is encoded as an empty object in JSON
-encode_jer_component_map([], MapVal, Acc) when map_size(MapVal) == length(Acc) ->
-    lists:reverse(Acc);
+encode_jer_component_map([], MapVal, Acc) when map_size(MapVal) =:= length(Acc) ->
+    maps:from_list(Acc);
 encode_jer_component_map(_, MapVal, Acc) ->
     ErroneousKeys = maps:keys(MapVal) -- [K || {K,_V} <- Acc],
     exit({error,{asn1,{{encode,'SEQUENCE'},{erroneous_keys,ErroneousKeys}}}}).
 
-
 encode_jer_component([{_Name, _Type, 'OPTIONAL'} | CompInfos], [asn1_NOVALUE | Rest], Acc) ->
     encode_jer_component(CompInfos, Rest, Acc);
 encode_jer_component([{_Name, _Type, {'DEFAULT',_}} | CompInfos], [asn1_DEFAULT | Rest], Acc) ->
@@ -195,10 +195,8 @@ encode_jer_component([{_Name, _Type, {'DEFAULT',_}} | CompInfos], [asn1_DEFAULT
 encode_jer_component([{Name, Type, _OptOrDefault} | CompInfos], [Value | Rest], Acc) ->
     Enc = encode_jer(Type, Value),
     encode_jer_component(CompInfos, Rest, [{Name,Enc}|Acc]);
-encode_jer_component([], _, []) ->
-    #{}; % ensure that it is encoded as an empty object in JSON
 encode_jer_component([], _, Acc) ->
-    lists:reverse(Acc).
+    maps:from_list(Acc).
 
 decode_jer(Module, Type, Val) ->
     TypeInfo = Module:typeinfo(Type),
-- 
2.35.3

openSUSE Build Service is sponsored by