/
JsonataExtensions.cs
196 lines (181 loc) · 9.25 KB
/
JsonataExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
using System;
using System.Collections.Generic;
using System.Globalization;
using Jsonata.Net.Native.Json;
namespace Jsonata.Net.Native.JsonNet
{
public static class JsonataExtensions
{
public static JToken FromNewtonsoft(Newtonsoft.Json.Linq.JToken value)
{
return FromNewtonsoft(value, CultureInfo.CurrentCulture);
}
/// <summary>
/// converts Newtonsoft.Json JToken to this Jsonata.Net.Native JToken using specific formatting for certain special Newtonsoft tokens
/// </summary>
/// <param name="value">a token to convert</param>
/// <param name="formatProvider">format provider used to format DateTime and TimeSpan. One may want to provide <see cref="CultureInfo.CurrentCulture"/> or <see cref="CultureInfo.InvariantCulture"/></param>
/// <param name="datetimeFormat">a standard or custom format string for <see cref="DateTime.ToString(string, IFormatProvider)"/><seealso cref="https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings"/><seealso cref="https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings"/></param>
/// <param name="timespanFormat">a standard or custom format string for <see cref="TimeSpan.ToString(string, IFormatProvider)"/><seealso cref="https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-timespan-format-strings"/><seealso cref="https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-timespan-format-strings"/> </param>
/// <param name="guidFormat">format string for <see cref="Guid.ToString(string, IFormatProvider)"/></param>
/// <returns>converted token</returns>
public static JToken FromNewtonsoft(
Newtonsoft.Json.Linq.JToken value,
IFormatProvider formatProvider,
string datetimeFormat = "G",
string timespanFormat = "c",
string guidFormat = "D"
)
{
switch (value.Type)
{
case Newtonsoft.Json.Linq.JTokenType.Array:
{
JArray result = new JArray();
foreach (Newtonsoft.Json.Linq.JToken child in value.Children())
{
result.Add(FromNewtonsoft(child, formatProvider, datetimeFormat, timespanFormat, guidFormat));
}
return result;
}
case Newtonsoft.Json.Linq.JTokenType.Boolean:
return new JValue((bool)value);
case Newtonsoft.Json.Linq.JTokenType.Float:
try
{
decimal decimalValue = (decimal)value;
return new JValue(decimalValue);
}
catch (OverflowException)
{
//throw new JsonataException("S0102", $"Number out of range: {value} ({ex.Message})");
return new JValue((double)value);
}
case Newtonsoft.Json.Linq.JTokenType.Integer:
return new JValue((long)value);
case Newtonsoft.Json.Linq.JTokenType.Null:
return JValue.CreateNull();
case Newtonsoft.Json.Linq.JTokenType.Object:
{
JObject result = new JObject();
foreach (Newtonsoft.Json.Linq.JProperty prop in ((Newtonsoft.Json.Linq.JObject)value).Properties())
{
result.Add(prop.Name, FromNewtonsoft(prop.Value, formatProvider, datetimeFormat, timespanFormat, guidFormat));
}
return result;
}
case Newtonsoft.Json.Linq.JTokenType.String:
return new JValue((string)value!);
case Newtonsoft.Json.Linq.JTokenType.Undefined:
return JValue.CreateUndefined();
case Newtonsoft.Json.Linq.JTokenType.Date:
return new JValue(((DateTime)value).ToString(datetimeFormat, formatProvider));
case Newtonsoft.Json.Linq.JTokenType.TimeSpan:
return new JValue(((TimeSpan)value).ToString(timespanFormat, formatProvider));
case Newtonsoft.Json.Linq.JTokenType.Uri:
return new JValue(((Uri)value!).ToString());
case Newtonsoft.Json.Linq.JTokenType.Guid:
return new JValue(((Guid)value).ToString(guidFormat));
case Newtonsoft.Json.Linq.JTokenType.Bytes:
case Newtonsoft.Json.Linq.JTokenType.Constructor:
case Newtonsoft.Json.Linq.JTokenType.Comment:
case Newtonsoft.Json.Linq.JTokenType.None:
case Newtonsoft.Json.Linq.JTokenType.Property:
case Newtonsoft.Json.Linq.JTokenType.Raw:
default:
throw new ArgumentException("Weird Token type " + value.Type);
}
}
/**
* <summary> may be used instead of JToken.FromObject() in case some custom converters are needed</summary>
*/
public static JToken FromObjectViaNewtonsoft(object? value, Newtonsoft.Json.JsonSerializer? serializer = null)
{
if (value == null)
{
return JValue.CreateNull();
};
Newtonsoft.Json.Linq.JToken token = Newtonsoft.Json.Linq.JToken.FromObject(value, serializer ?? Newtonsoft.Json.JsonSerializer.CreateDefault());
return JsonataExtensions.FromNewtonsoft(token);
}
public static Newtonsoft.Json.Linq.JToken ToNewtonsoft(this JToken value)
{
switch (value.Type)
{
case JTokenType.Array:
{
JArray source = (JArray)value;
Newtonsoft.Json.Linq.JArray result = new Newtonsoft.Json.Linq.JArray();
foreach (JToken child in source.ChildrenTokens)
{
result.Add(ToNewtonsoft(child));
}
return result;
}
case JTokenType.Object:
{
JObject source = (JObject)value;
Newtonsoft.Json.Linq.JObject result = new Newtonsoft.Json.Linq.JObject();
foreach (KeyValuePair<string, JToken> prop in source.Properties)
{
result.Add(prop.Key, ToNewtonsoft(prop.Value));
}
return result;
}
case JTokenType.Function:
throw new NotSupportedException("Not supported for functions");
case JTokenType.Null:
return Newtonsoft.Json.Linq.JValue.CreateNull();
case JTokenType.Undefined:
return Newtonsoft.Json.Linq.JValue.CreateUndefined();
case JTokenType.Float:
try
{
decimal decimalValue = (decimal)value;
return new Newtonsoft.Json.Linq.JValue(decimalValue);
}
catch (OverflowException)
{
//throw new JsonataException("S0102", $"Number out of range: {value} ({ex.Message})");
return new Newtonsoft.Json.Linq.JValue((double)value);
}
case JTokenType.Integer:
return new Newtonsoft.Json.Linq.JValue((long)value);
case JTokenType.String:
return Newtonsoft.Json.Linq.JValue.CreateString((string)value);
case JTokenType.Boolean:
return new Newtonsoft.Json.Linq.JValue((bool)value);
default:
throw new Exception("Unexpected type " + value.Type);
}
}
public static string EvalNewtonsoft(this JsonataQuery query, string dataJson)
{
Newtonsoft.Json.Linq.JToken data = Newtonsoft.Json.Linq.JToken.Parse(dataJson);
JToken result = query.Eval(JsonataExtensions.FromNewtonsoft(data));
return result.ToIndentedString();
}
public static Newtonsoft.Json.Linq.JToken EvalNewtonsoft(this JsonataQuery query, Newtonsoft.Json.Linq.JToken data, Newtonsoft.Json.Linq.JObject? bindings = null)
{
EvaluationEnvironment env;
if (bindings != null)
{
env = new EvaluationEnvironment((JObject)JsonataExtensions.FromNewtonsoft(bindings));
}
else
{
env = EvaluationEnvironment.DefaultEnvironment;
};
return EvalNewtonsoft(query, data, env);
}
public static Newtonsoft.Json.Linq.JToken EvalNewtonsoft(this JsonataQuery query, Newtonsoft.Json.Linq.JToken data, EvaluationEnvironment environment)
{
JToken result = query.Eval(JsonataExtensions.FromNewtonsoft(data), environment);
return result.ToNewtonsoft();
}
public static void BindValue(this EvaluationEnvironment env, string name, Newtonsoft.Json.Linq.JToken value)
{
env.BindValue(name, JsonataExtensions.FromNewtonsoft(value)); //allow overrides
}
}
}