1717// under the License.
1818// </copyright>
1919
20+ using System ;
2021using System . Collections . Generic ;
22+ using System . Linq ;
23+ using System . Numerics ;
2124using System . Text . Json . Serialization ;
2225
2326namespace OpenQA . Selenium . BiDi . Modules . Script ;
@@ -38,33 +41,98 @@ namespace OpenQA.Selenium.BiDi.Modules.Script;
3841[ JsonDerivedType ( typeof ( SetLocalValue ) , "set" ) ]
3942public abstract record LocalValue
4043{
41- public static implicit operator LocalValue ( int value ) { return new NumberLocalValue ( value ) ; }
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 ( ) ; }
4247 public static implicit operator LocalValue ( string ? value ) { return value is null ? new NullLocalValue ( ) : new StringLocalValue ( value ) ; }
4348
4449 // TODO: Extend converting from types
4550 public static LocalValue ConvertFrom ( object ? value )
4651 {
4752 switch ( value )
4853 {
49- case LocalValue :
50- return ( LocalValue ) value ;
54+ case LocalValue localValue :
55+ return localValue ;
56+
5157 case null :
5258 return new NullLocalValue ( ) ;
53- case int :
54- return ( int ) value ;
55- case string :
56- return ( string ) value ;
57- case object :
59+
60+ case bool b :
61+ return new BooleanLocalValue ( b ) ;
62+
63+ case int i :
64+ return new NumberLocalValue ( i ) ;
65+
66+ case double d :
67+ return new NumberLocalValue ( d ) ;
68+
69+ case long l :
70+ return new NumberLocalValue ( l ) ;
71+
72+ case DateTime dt :
73+ return new DateLocalValue ( dt . ToString ( "o" ) ) ;
74+
75+ case BigInteger bigInt :
76+ return new BigIntLocalValue ( bigInt . ToString ( ) ) ;
77+
78+ case string str :
79+ return new StringLocalValue ( str ) ;
80+
81+ case IDictionary < string , string ? > dictionary :
5882 {
59- var type = value . GetType ( ) ;
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+ }
6088
61- var properties = type . GetProperties ( System . Reflection . BindingFlags . Public | System . Reflection . BindingFlags . Instance ) ;
89+ return new ObjectLocalValue ( bidiObject ) ;
90+ }
91+
92+ 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+ }
102+
103+ 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+ }
113+
114+ 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 ;
62120
63- List < List < LocalValue > > values = [ ] ;
121+ var properties = value . GetType ( ) . GetProperties ( Flags ) ;
64122
123+ var values = new List < List < LocalValue > > ( properties . Length ) ;
65124 foreach ( var property in properties )
66125 {
67- values . Add ( [ property. Name , ConvertFrom ( property . GetValue ( value ) ) ] ) ;
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 ) ] ) ;
68136 }
69137
70138 return new ObjectLocalValue ( values ) ;
0 commit comments