1212using System . Text . Encodings . Web ;
1313using System . Text . Json . Serialization ;
1414
15+ using NodaTime ;
16+
1517using VMelnalksnis . PaperlessDotNet . Documents ;
1618using VMelnalksnis . PaperlessDotNet . DocumentTypes ;
1719
@@ -94,40 +96,43 @@ private static KeyValuePair<string, string> ToKeyValuePair(this Expression expre
9496 {
9597 if ( expression is BinaryExpression binaryExpression )
9698 {
97- var suffix = binaryExpression . GetSuffix ( ) ;
98-
9999 if ( binaryExpression . Left is MemberExpression memberExpression )
100100 {
101- var value = binaryExpression . Right . Evaluate ( ) ;
102- if ( value is bool boolValue )
101+ var memberName = memberExpression . GetFilterMemberName ( ) ;
102+
103+ var suffix = binaryExpression . GetSuffix ( ) ;
104+ if ( suffix is not null )
103105 {
104- value = binaryExpression . NodeType is NotEqual
105- ? ! boolValue
106- : boolValue ;
106+ memberName += $ "__{ suffix } ";
107107 }
108- else if ( value is null )
108+
109+ if ( binaryExpression . Right . Type == typeof ( bool ) )
109110 {
110- value = binaryExpression . NodeType is Equal ;
111+ var booleanValue = binaryExpression . Right . Evaluate < bool > ( ) ;
112+ booleanValue = binaryExpression . NodeType is NotEqual
113+ ? ! booleanValue
114+ : booleanValue ;
115+
116+ return new ( memberName , booleanValue ? "true" : "false" ) ;
111117 }
112118
113- var memberName = memberExpression . GetFilterMemberName ( ) ;
119+ if ( binaryExpression . Right . Type == typeof ( DateTime ) )
120+ {
121+ var dateValue = binaryExpression . Right . Evaluate < DateTime > ( ) ;
122+ var dateString = memberName . Contains ( "__date" )
123+ ? dateValue . ToString ( "yyyy-MM-dd" , CultureInfo . InvariantCulture )
124+ : dateValue . ToString ( "yyyy-MM-ddTHH:mm:ss" , CultureInfo . InvariantCulture ) ;
114125
115- if ( suffix is not null )
126+ return new ( memberName , dateString ) ;
127+ }
128+
129+ var value = binaryExpression . Right . Evaluate ( ) ;
130+ if ( value is null )
116131 {
117- memberName += $ "__ { suffix } " ;
132+ return new ( memberName , binaryExpression . NodeType is Equal ? "true" : "false" ) ;
118133 }
119134
120- return new (
121- memberName ,
122- value switch
123- {
124- DateTime dateTime when memberName . Contains ( "__date" ) => dateTime . ToString (
125- "yyyy-MM-dd" ,
126- CultureInfo . InvariantCulture ) ,
127- DateTime dateTime => dateTime . ToString ( "yyyy-MM-ddTHH:mm:ss" , CultureInfo . InvariantCulture ) ,
128- bool boolean => boolean . ToString ( ) . ToLowerInvariant ( ) ,
129- _ => value . ToString ( ) ?? string . Empty ,
130- } ) ;
135+ return new ( memberName , value . ToString ( ) ?? string . Empty ) ;
131136 }
132137 }
133138
@@ -144,7 +149,8 @@ DateTime dateTime when memberName.Contains("__date") => dateTime.ToString(
144149 _ => throw new NotImplementedException ( ) ,
145150 } ;
146151
147- var value = valueExpression . Evaluate ( ) ?? throw new NotSupportedException ( "Method calls with null arguments are not supported" ) ;
152+ var value = valueExpression . Evaluate ( ) ??
153+ throw new NotSupportedException ( "Method calls with null arguments are not supported" ) ;
148154 if ( value is IEnumerable < int > values )
149155 {
150156 suffix = "in" ;
@@ -158,7 +164,8 @@ DateTime dateTime when memberName.Contains("__date") => dateTime.ToString(
158164 }
159165 else
160166 {
161- var value = methodCallExpression . Arguments [ 0 ] . Evaluate ( ) ?? throw new InvalidOperationException ( "Extension method calls on null instances are not supported" ) ;
167+ var value = methodCallExpression . Arguments [ 0 ] . Evaluate ( ) ??
168+ throw new InvalidOperationException ( "Extension method calls on null instances are not supported" ) ;
162169 if ( value is IEnumerable < int > values )
163170 {
164171 suffix = "in" ;
@@ -232,6 +239,116 @@ private static string GetOrderMemberName(this MemberExpression expression)
232239
233240 private static object ? Evaluate ( this Expression expression )
234241 {
235- return Expression . Lambda ( expression ) . Compile ( ) . DynamicInvoke ( ) ;
242+ if ( expression . Type == typeof ( string ) )
243+ {
244+ return expression . Evaluate < string ? > ( ) ;
245+ }
246+
247+ if ( expression . Type == typeof ( Uri ) )
248+ {
249+ return expression . Evaluate < Uri ? > ( ) ;
250+ }
251+
252+ if ( expression . Type == typeof ( int ) )
253+ {
254+ return expression . Evaluate < int > ( ) ;
255+ }
256+
257+ if ( expression . Type == typeof ( int ? ) )
258+ {
259+ return expression . Evaluate < int ? > ( ) ;
260+ }
261+
262+ if ( expression . Type == typeof ( uint ) )
263+ {
264+ return expression . Evaluate < uint > ( ) ;
265+ }
266+
267+ if ( expression . Type == typeof ( uint ? ) )
268+ {
269+ return expression . Evaluate < uint ? > ( ) ;
270+ }
271+
272+ if ( expression . Type == typeof ( float ) )
273+ {
274+ return expression . Evaluate < float > ( ) ;
275+ }
276+
277+ if ( expression . Type == typeof ( float ? ) )
278+ {
279+ return expression . Evaluate < float ? > ( ) ;
280+ }
281+
282+ if ( expression . Type == typeof ( double ) )
283+ {
284+ return expression . Evaluate < double > ( ) ;
285+ }
286+
287+ if ( expression . Type == typeof ( double ? ) )
288+ {
289+ return expression . Evaluate < double ? > ( ) ;
290+ }
291+
292+ if ( expression . Type == typeof ( decimal ) )
293+ {
294+ return expression . Evaluate < decimal > ( ) ;
295+ }
296+
297+ if ( expression . Type == typeof ( decimal ? ) )
298+ {
299+ return expression . Evaluate < decimal ? > ( ) ;
300+ }
301+
302+ if ( expression . Type == typeof ( bool ) )
303+ {
304+ return expression . Evaluate < bool > ( ) ;
305+ }
306+
307+ if ( expression . Type == typeof ( bool ? ) )
308+ {
309+ return expression . Evaluate < bool ? > ( ) ;
310+ }
311+
312+ if ( expression . Type == typeof ( DateTime ) )
313+ {
314+ return expression . Evaluate < DateTime > ( ) ;
315+ }
316+
317+ if ( expression . Type == typeof ( DateTime ? ) )
318+ {
319+ return expression . Evaluate < DateTime ? > ( ) ;
320+ }
321+
322+ if ( expression . Type == typeof ( OffsetDate ) )
323+ {
324+ return expression . Evaluate < OffsetDate > ( ) ;
325+ }
326+
327+ if ( expression . Type == typeof ( OffsetDate ? ) )
328+ {
329+ return expression . Evaluate < OffsetDate ? > ( ) ;
330+ }
331+
332+ if ( expression . Type == typeof ( LocalDate ) )
333+ {
334+ return expression . Evaluate < LocalDate > ( ) ;
335+ }
336+
337+ if ( expression . Type == typeof ( LocalDate ? ) )
338+ {
339+ return expression . Evaluate < LocalDate ? > ( ) ;
340+ }
341+
342+ if ( typeof ( IEnumerable < int > ) . IsAssignableFrom ( expression . Type ) )
343+ {
344+ return expression . Evaluate < IEnumerable < int > > ( ) ;
345+ }
346+
347+ throw new ArgumentOutOfRangeException ( nameof ( expression . Type ) , expression . Type , "Unsupported expression type" ) ;
348+ }
349+
350+ private static TValue Evaluate < TValue > ( this Expression expression )
351+ {
352+ return Expression . Lambda < Func < TValue > > ( expression ) . Compile ( ) . Invoke ( ) ;
236353 }
237354}
0 commit comments