@@ -41,10 +41,10 @@ namespace OpenQA.Selenium.BiDi.Modules.Script;
4141[ JsonDerivedType ( typeof ( SetLocalValue ) , "set" ) ]
4242public 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