Skip to content

Commit 742b386

Browse files
committed
[dotnet] [bidi] Add strongly-typed LocalValue.ConvertFrom overloads
1 parent 99419ef commit 742b386

File tree

1 file changed

+219
-63
lines changed

1 file changed

+219
-63
lines changed

dotnet/src/webdriver/BiDi/Modules/Script/LocalValue.cs

Lines changed: 219 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ namespace OpenQA.Selenium.BiDi.Modules.Script;
4141
[JsonDerivedType(typeof(SetLocalValue), "set")]
4242
public abstract record LocalValue
4343
{
44-
public static implicit operator LocalValue(bool? value) { return value is bool b ? new BooleanLocalValue(b) : new NullLocalValue(); }
45-
public static implicit operator LocalValue(int? value) { return value is int i ? new NumberLocalValue(i) : new NullLocalValue(); }
46-
public static implicit operator LocalValue(double? value) { return value is double d ? new NumberLocalValue(d) : new NullLocalValue(); }
47-
public static implicit operator LocalValue(string? value) { return value is null ? new NullLocalValue() : new StringLocalValue(value); }
44+
public static implicit operator LocalValue(bool? value) { return ConvertFrom(value); }
45+
public static implicit operator LocalValue(int? value) { return ConvertFrom(value); }
46+
public static implicit operator LocalValue(double? value) { return ConvertFrom(value); }
47+
public static implicit operator LocalValue(string? value) { return ConvertFrom(value); }
4848

4949
// TODO: Extend converting from types
5050
public static LocalValue ConvertFrom(object? value)
@@ -58,86 +58,242 @@ public static LocalValue ConvertFrom(object? value)
5858
return new NullLocalValue();
5959

6060
case bool b:
61-
return new BooleanLocalValue(b);
61+
return ConvertFrom(b);
6262

6363
case int i:
64-
return new NumberLocalValue(i);
64+
return ConvertFrom(i);
6565

6666
case double d:
67-
return new NumberLocalValue(d);
67+
return ConvertFrom(d);
6868

6969
case long l:
70-
return new NumberLocalValue(l);
70+
return ConvertFrom(l);
7171

7272
case DateTime dt:
73-
return new DateLocalValue(dt.ToString("o"));
73+
return ConvertFrom(dt);
7474

7575
case BigInteger bigInt:
76-
return new BigIntLocalValue(bigInt.ToString());
76+
return ConvertFrom(bigInt);
7777

7878
case string str:
79-
return new StringLocalValue(str);
79+
return ConvertFrom(str);
8080

8181
case IDictionary<string, string?> dictionary:
82-
{
83-
var bidiObject = new List<List<LocalValue>>(dictionary.Count);
84-
foreach (var item in dictionary)
85-
{
86-
bidiObject.Add([new StringLocalValue(item.Key), ConvertFrom(item.Value)]);
87-
}
88-
89-
return new ObjectLocalValue(bidiObject);
90-
}
82+
return ConvertFrom(dictionary);
9183

9284
case IDictionary<string, object?> dictionary:
93-
{
94-
var bidiObject = new List<List<LocalValue>>(dictionary.Count);
95-
foreach (var item in dictionary)
96-
{
97-
bidiObject.Add([new StringLocalValue(item.Key), ConvertFrom(item.Value)]);
98-
}
99-
100-
return new ObjectLocalValue(bidiObject);
101-
}
85+
return ConvertFrom(dictionary);
10286

10387
case IDictionary<int, object?> dictionary:
104-
{
105-
var bidiObject = new List<List<LocalValue>>(dictionary.Count);
106-
foreach (var item in dictionary)
107-
{
108-
bidiObject.Add([ConvertFrom(item.Key), ConvertFrom(item.Value)]);
109-
}
110-
111-
return new MapLocalValue(bidiObject);
112-
}
88+
return ConvertFrom(dictionary);
11389

11490
case IEnumerable<object?> list:
115-
return new ArrayLocalValue(list.Select(ConvertFrom).ToList());
116-
117-
case object:
118-
{
119-
const System.Reflection.BindingFlags Flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance;
120-
121-
var properties = value.GetType().GetProperties(Flags);
122-
123-
var values = new List<List<LocalValue>>(properties.Length);
124-
foreach (var property in properties)
125-
{
126-
object? propertyValue;
127-
try
128-
{
129-
propertyValue = property.GetValue(value);
130-
}
131-
catch (Exception ex)
132-
{
133-
throw new BiDiException($"Could not retrieve property {property.Name} from {property.DeclaringType}", ex);
134-
}
135-
values.Add([property.Name, ConvertFrom(propertyValue)]);
136-
}
137-
138-
return new ObjectLocalValue(values);
139-
}
91+
return ConvertFrom(list);
92+
93+
default:
94+
return ReflectionBasedConvertFrom(value);
95+
}
96+
}
97+
98+
public static LocalValue ConvertFrom(bool value)
99+
{
100+
return new BooleanLocalValue(value);
101+
}
102+
103+
public static LocalValue ConvertFrom(bool? value)
104+
{
105+
if (value is bool b)
106+
{
107+
return new BooleanLocalValue(b);
108+
}
109+
110+
return new NullLocalValue();
111+
}
112+
113+
public static LocalValue ConvertFrom(int value)
114+
{
115+
return new NumberLocalValue(value);
116+
}
117+
118+
public static LocalValue ConvertFrom(int? value)
119+
{
120+
if (value is int b)
121+
{
122+
return new NumberLocalValue(b);
123+
}
124+
125+
return new NullLocalValue();
126+
}
127+
128+
public static LocalValue ConvertFrom(double value)
129+
{
130+
return new NumberLocalValue(value);
131+
}
132+
133+
public static LocalValue ConvertFrom(double? value)
134+
{
135+
if (value is double b)
136+
{
137+
return new NumberLocalValue(b);
138+
}
139+
140+
return new NullLocalValue();
141+
}
142+
143+
public static LocalValue ConvertFrom(long value)
144+
{
145+
return new NumberLocalValue(value);
146+
}
147+
148+
public static LocalValue ConvertFrom(long? value)
149+
{
150+
if (value is long b)
151+
{
152+
return new NumberLocalValue(b);
153+
}
154+
155+
return new NullLocalValue();
156+
}
157+
158+
public static LocalValue ConvertFrom(string? value)
159+
{
160+
if (value is not null)
161+
{
162+
return new StringLocalValue(value);
163+
}
164+
165+
return new NullLocalValue();
166+
}
167+
168+
public static LocalValue ConvertFrom(DateTime dateTime)
169+
{
170+
return new DateLocalValue(dateTime.ToString("o"));
171+
}
172+
173+
public static LocalValue ConvertFrom(BigInteger bigInt)
174+
{
175+
return new BigIntLocalValue(bigInt.ToString());
176+
}
177+
178+
public static LocalValue ConvertFrom(IEnumerable<object?>? values)
179+
{
180+
if (values is null)
181+
{
182+
return new NullLocalValue();
140183
}
184+
185+
LocalValue[] convertedList = values.Select(ConvertFrom).ToArray();
186+
return new ArrayLocalValue(convertedList);
187+
}
188+
189+
public static LocalValue ConvertFrom(List<string?>? values)
190+
{
191+
if (values is null)
192+
{
193+
return new NullLocalValue();
194+
}
195+
196+
List<LocalValue> convertedList = values.ConvertAll(ConvertFrom);
197+
return new ArrayLocalValue(convertedList);
198+
}
199+
200+
public static LocalValue ConvertFrom(object?[]? values)
201+
{
202+
if (values is null)
203+
{
204+
return new NullLocalValue();
205+
}
206+
207+
LocalValue[] convertedArray = Array.ConvertAll(values, ConvertFrom);
208+
return new ArrayLocalValue(Array.ConvertAll(values, ConvertFrom));
209+
}
210+
211+
public static LocalValue ConvertFrom(IList<object?>? values)
212+
{
213+
if (values is null)
214+
{
215+
return new NullLocalValue();
216+
}
217+
218+
List<LocalValue> convertedList = [.. values.Select(ConvertFrom)];
219+
return new ArrayLocalValue(convertedList);
220+
}
221+
222+
public static LocalValue ConvertFrom(IDictionary<string, string?>? dictionary)
223+
{
224+
if (dictionary is null)
225+
{
226+
return new NullLocalValue();
227+
}
228+
229+
var bidiObject = new List<List<LocalValue>>(dictionary.Count);
230+
foreach (KeyValuePair<string, string?> item in dictionary)
231+
{
232+
bidiObject.Add([ConvertFrom(item.Key), ConvertFrom(item.Value)]);
233+
}
234+
235+
return new ObjectLocalValue(bidiObject);
236+
}
237+
238+
public static LocalValue ConvertFrom(IDictionary<string, object?>? dictionary)
239+
{
240+
if (dictionary is null)
241+
{
242+
return new NullLocalValue();
243+
}
244+
245+
var bidiObject = new List<List<LocalValue>>(dictionary.Count);
246+
foreach (KeyValuePair<string, object?> item in dictionary)
247+
{
248+
bidiObject.Add([ConvertFrom(item.Key), ConvertFrom(item.Value)]);
249+
}
250+
251+
return new ObjectLocalValue(bidiObject);
252+
}
253+
254+
public static LocalValue ConvertFrom(IDictionary<int, object?>? dictionary)
255+
{
256+
if (dictionary is null)
257+
{
258+
return new NullLocalValue();
259+
}
260+
261+
var bidiObject = new List<List<LocalValue>>(dictionary.Count);
262+
foreach (KeyValuePair<int, object?> item in dictionary)
263+
{
264+
bidiObject.Add([ConvertFrom(item.Key), ConvertFrom(item.Value)]);
265+
}
266+
267+
return new MapLocalValue(bidiObject);
268+
}
269+
270+
private static LocalValue ReflectionBasedConvertFrom(object? value)
271+
{
272+
if (value is null)
273+
{
274+
return new NullLocalValue();
275+
}
276+
277+
const System.Reflection.BindingFlags Flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance;
278+
279+
System.Reflection.PropertyInfo[] properties = value.GetType().GetProperties(Flags);
280+
281+
var values = new List<List<LocalValue>>(properties.Length);
282+
foreach (System.Reflection.PropertyInfo? property in properties)
283+
{
284+
object? propertyValue;
285+
try
286+
{
287+
propertyValue = property.GetValue(value);
288+
}
289+
catch (Exception ex)
290+
{
291+
throw new BiDiException($"Could not retrieve property {property.Name} from {property.DeclaringType}", ex);
292+
}
293+
values.Add([property.Name, ConvertFrom(propertyValue)]);
294+
}
295+
296+
return new ObjectLocalValue(values);
141297
}
142298
}
143299

0 commit comments

Comments
 (0)