@@ -36,98 +36,108 @@ public static TranslatedExpression Translate(TranslationContext context, MethodC
36
36
throw new ExpressionNotSupportedException ( expression ) ;
37
37
}
38
38
39
- ByteOrder ? byteOrder = null ;
40
- string format = null ;
41
- AstExpression onErrorAst = null ;
42
- AstExpression onNullAst = null ;
43
- BsonBinarySubType ? subType = null ;
44
-
45
39
var fieldAst = ExpressionToAggregationExpressionTranslator . Translate ( context , arguments [ 0 ] ) . Ast ;
46
40
47
- var optionExpression = arguments [ 1 ] ;
41
+ ByteOrder ? byteOrder ;
42
+ string format ;
43
+ AstExpression onErrorAst ;
44
+ AstExpression onNullAst ;
45
+ BsonBinarySubType ? subType ;
48
46
49
- if ( optionExpression is ConstantExpression constantExpression )
47
+ var optionExpression = arguments [ 1 ] ;
48
+ switch ( optionExpression )
50
49
{
51
- var options = ( ConvertOptions ) constantExpression . Value ;
50
+ case ConstantExpression constantExpression :
51
+ ExtractOptionsFromConstantExpression ( constantExpression , out byteOrder , out format , out onErrorAst , out onNullAst , out subType ) ;
52
+ break ;
53
+ case MemberInitExpression memberInitExpression :
54
+ ExtractOptionsFromMemberInitExpression ( memberInitExpression , context , out byteOrder , out format , out onErrorAst , out onNullAst , out subType ) ;
55
+ break ;
56
+ default :
57
+ throw new ExpressionNotSupportedException ( "The 'Options' argument can be either a constant expression or a member initialization expression" ) ;
58
+ }
52
59
53
- if ( options . OnErrorWasSet )
54
- {
55
- onErrorAst = options . GetOnError ( ) ;
56
- }
60
+ var toType = method . GetGenericArguments ( ) [ 1 ] ;
61
+ var toBsonType = GetBsonType ( toType ) . Render ( ) ;
62
+ var serializer = BsonSerializer . LookupSerializer ( toType ) ;
57
63
58
- if ( options . OnNullWasSet )
59
- {
60
- onNullAst = options . GetOnNull ( ) ;
61
- }
64
+ var ast = AstExpression . Convert ( fieldAst , toBsonType , subType : subType , byteOrder : byteOrder , format : format , onError : onErrorAst , onNull : onNullAst ) ;
65
+ return new TranslatedExpression ( expression , ast , serializer ) ;
66
+ }
67
+
68
+ private static void ExtractOptionsFromConstantExpression ( ConstantExpression constantExpression , out ByteOrder ? byteOrder , out string format , out AstExpression onErrorAst , out AstExpression onNullAst , out BsonBinarySubType ? subType )
69
+ {
70
+ byteOrder = null ;
71
+ format = null ;
72
+ onErrorAst = null ;
73
+ onNullAst = null ;
74
+ subType = null ;
62
75
63
- subType = options . SubType ;
64
- format = options . Format ;
65
- byteOrder = options . ByteOrder ;
76
+ var options = ( ConvertOptions ) constantExpression . Value ;
77
+
78
+ if ( options is null )
79
+ {
80
+ return ;
66
81
}
67
- else if ( optionExpression is MemberInitExpression memberInitExpression )
82
+
83
+ if ( options . OnErrorWasSet )
68
84
{
69
- foreach ( var binding in memberInitExpression . Bindings )
70
- {
71
- if ( binding is not MemberAssignment memberAssignment ) continue ;
72
-
73
- var memberName = memberAssignment . Member . Name ;
74
-
75
- switch ( memberName )
76
- {
77
- case nameof ( ConvertOptions . ByteOrder ) :
78
- {
79
- if ( memberAssignment . Expression is not ConstantExpression byteOrderExpression )
80
- {
81
- throw new ExpressionNotSupportedException ( $ "The { nameof ( ConvertOptions . ByteOrder ) } field must be a constant expression") ; //TODO Improve message?
82
- }
83
-
84
- byteOrder = ( ByteOrder ? ) byteOrderExpression . Value ;
85
- break ;
86
- }
87
- case nameof ( ConvertOptions . Format ) :
88
- {
89
- if ( memberAssignment . Expression is not ConstantExpression formatExpression )
90
- {
91
- throw new ExpressionNotSupportedException ( $ "The { nameof ( ConvertOptions . Format ) } field must be a constant expression") ; //TODO Improve message?
92
- }
93
-
94
- format = ( string ) formatExpression . Value ;
95
- break ;
96
- }
97
- case nameof ( ConvertOptions < object > . OnError ) :
98
- {
99
- onErrorAst = ExpressionToAggregationExpressionTranslator . Translate ( context , memberAssignment . Expression ) . Ast ;
100
- break ;
101
- }
102
- case nameof ( ConvertOptions < object > . OnNull ) :
103
- {
104
- onNullAst = ExpressionToAggregationExpressionTranslator . Translate ( context , memberAssignment . Expression ) . Ast ;
105
- break ;
106
- }
107
- case nameof ( ConvertOptions . SubType ) :
108
- {
109
- if ( memberAssignment . Expression is not ConstantExpression subTypeExpression )
110
- {
111
- throw new ExpressionNotSupportedException ( $ "The { nameof ( ConvertOptions . SubType ) } field must be a constant expression") ; //TODO Improve message?
112
- }
113
-
114
- subType = ( BsonBinarySubType ? ) subTypeExpression . Value ;
115
- break ;
116
- }
117
- }
118
- }
85
+ onErrorAst = options . GetOnError ( ) ;
119
86
}
120
- else
87
+
88
+ if ( options . OnNullWasSet )
121
89
{
122
- throw new ExpressionNotSupportedException ( "The 'Options' argument can be either a constant expression or a member initialization expression" ) ; //TODO Improve message?
90
+ onNullAst = options . GetOnNull ( ) ;
123
91
}
124
92
125
- var toType = method . GetGenericArguments ( ) [ 1 ] ;
126
- var toBsonType = GetBsonType ( toType ) . Render ( ) ;
127
- var serializer = BsonSerializer . LookupSerializer ( toType ) ;
93
+ subType = options . SubType ;
94
+ format = options . Format ;
95
+ byteOrder = options . ByteOrder ;
96
+ }
128
97
129
- var ast = AstExpression . Convert ( fieldAst , toBsonType , subType : subType , byteOrder : byteOrder , format : format , onError : onErrorAst , onNull : onNullAst ) ;
130
- return new TranslatedExpression ( expression , ast , serializer ) ;
98
+ private static void ExtractOptionsFromMemberInitExpression ( MemberInitExpression memberInitExpression , TranslationContext context , out ByteOrder ? byteOrder , out string format , out AstExpression onErrorAst , out AstExpression onNullAst , out BsonBinarySubType ? subType )
99
+ {
100
+ byteOrder = null ;
101
+ format = null ;
102
+ onErrorAst = null ;
103
+ onNullAst = null ;
104
+ subType = null ;
105
+
106
+ foreach ( var binding in memberInitExpression . Bindings )
107
+ {
108
+ if ( binding is not MemberAssignment memberAssignment ) continue ;
109
+
110
+ var memberName = memberAssignment . Member . Name ;
111
+ var expression = memberAssignment . Expression ;
112
+
113
+ switch ( memberName )
114
+ {
115
+ case nameof ( ConvertOptions . ByteOrder ) :
116
+ byteOrder = GetConstantValue < ByteOrder ? > ( expression , nameof ( ConvertOptions . ByteOrder ) ) ;
117
+ break ;
118
+ case nameof ( ConvertOptions . Format ) :
119
+ format = GetConstantValue < string > ( expression , nameof ( ConvertOptions . Format ) ) ;
120
+ break ;
121
+ case nameof ( ConvertOptions < object > . OnError ) :
122
+ onErrorAst = ExpressionToAggregationExpressionTranslator . Translate ( context , expression ) . Ast ;
123
+ break ;
124
+ case nameof ( ConvertOptions < object > . OnNull ) :
125
+ onNullAst = ExpressionToAggregationExpressionTranslator . Translate ( context , expression ) . Ast ;
126
+ break ;
127
+ case nameof ( ConvertOptions . SubType ) :
128
+ subType = GetConstantValue < BsonBinarySubType ? > ( expression , nameof ( ConvertOptions . SubType ) ) ;
129
+ break ;
130
+ }
131
+ }
132
+ }
133
+
134
+ private static T GetConstantValue < T > ( Expression expression , string fieldName )
135
+ {
136
+ if ( expression is not ConstantExpression constantExpression )
137
+ {
138
+ throw new ExpressionNotSupportedException ( $ "The { fieldName } field must be a constant expression.") ;
139
+ }
140
+ return ( T ) constantExpression . Value ;
131
141
}
132
142
133
143
private static BsonType GetBsonType ( Type type ) //TODO Do we have this kind of info somewhere else...?
0 commit comments