1+ // Copyright (c) Winton. All rights reserved. 
2+ // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 
3+ 
4+ using  System ; 
5+ using  System . Threading . Tasks ; 
6+ using  Microsoft . AspNetCore . Mvc ; 
7+ 
8+ namespace  Winton . DomainModelling . AspNetCore 
9+ { 
10+     /// <summary> 
11+     ///     Extension methods for converting <see cref="Result{TData}"/> types into <see cref="IActionResult"/> types. 
12+     /// </summary> 
13+     public  static   class  ResultExtensions 
14+     { 
15+         /// <summary> 
16+         ///     Converts a <see cref="Result{Unit}"/> to an <see cref="IActionResult"/>. 
17+         /// </summary> 
18+         /// <param name="result"> 
19+         ///     The result that this extension method is invoked on. 
20+         /// </param> 
21+         /// <returns> 
22+         ///     If this result is a success then a <see cref="NoContentResult"/> is returned; 
23+         ///     otherwise it is converted to the appropriate 4xx response with Problem Details 
24+         ///     containing information about the error. 
25+         /// </returns> 
26+         public  static   IActionResult  ToActionResult ( this  Result < Unit >  result ) 
27+         { 
28+             return  result . ToActionResult ( null  as  Func < Error ,  ProblemDetails > ) ; 
29+         } 
30+ 
31+         /// <summary> 
32+         ///     Converts a <see cref="Result{Unit}"/> to an <see cref="IActionResult"/>. 
33+         /// </summary> 
34+         /// <param name="result"> 
35+         ///     The result that this extension method is invoked on. 
36+         /// </param> 
37+         /// <param name="onError"> 
38+         ///     The function that is invoked if this <paramref name="result"/> is a <see cref="Failure{TData}"/>. 
39+         ///     It is responsible for mapping the <see cref="Error"/> to <see cref="ProblemDetails"/>. 
40+         ///     If this function returns <code>null</code> then the default error mapping conventions are used. 
41+         ///     This therefore provides a way to customize the error mapping from <see cref="Error"/> to <see cref="ProblemDetails"/>. 
42+         /// </param> 
43+         /// <returns> 
44+         ///     If this result is a success then a <see cref="NoContentResult"/> is returned; 
45+         ///     otherwise it is converted to an error response containing <see cref="ProblemDetails"/> 
46+         ///     in the response body. 
47+         /// </returns> 
48+         public  static   IActionResult  ToActionResult ( 
49+             this  Result < Unit >  result , 
50+             Func < Error ,  ProblemDetails >  onError ) 
51+         { 
52+             return  result . Match ( _ =>  new  NoContentResult ( ) ,  error =>  error . ToActionResult ( onError ) ) ; 
53+         } 
54+ 
55+         /// <summary> 
56+         ///     Converts a <see cref="Task{Result}"/> of a <see cref="Result{Unit}"/> to an <see cref="IActionResult"/>. 
57+         /// </summary> 
58+         /// <param name="resultTask"> 
59+         ///     The asynchronous result that this extension method is invoked on. 
60+         /// </param> 
61+         /// <returns> 
62+         ///     If this result is a success then a <see cref="NoContentResult"/> is returned; 
63+         ///     otherwise it is converted to the appropriate 4xx response containing <see cref="ProblemDetails"/> 
64+         ///     in the response body. 
65+         /// </returns> 
66+         public  static   async  Task < IActionResult >  ToActionResult ( this  Task < Result < Unit > >  resultTask ) 
67+         { 
68+             return  ( await  resultTask ) . ToActionResult ( ) ; 
69+         } 
70+ 
71+         /// <summary> 
72+         ///     Converts a <see cref="Task{Result}"/> of a <see cref="Result{Unit}"/> to an <see cref="IActionResult"/>. 
73+         /// </summary> 
74+         /// <param name="resultTask"> 
75+         ///     The asynchronous result that this extension method is invoked on. 
76+         /// </param> 
77+         /// <param name="onError"> 
78+         ///     The function that is invoked if this <paramref name="resultTask"/> is a <see cref="Failure{TData}"/>. 
79+         ///     It is responsible for mapping the <see cref="Error"/> to <see cref="ProblemDetails"/>. 
80+         ///     If this function returns <code>null</code> then the default error mapping conventions are used. 
81+         ///     This therefore provides a way to customize the error mapping from <see cref="Error"/> to <see cref="ProblemDetails"/>. 
82+         /// </param> 
83+         /// <returns> 
84+         ///     If this result is a success then a <see cref="NoContentResult"/> is returned; 
85+         ///     otherwise it is converted to an error response containing <see cref="ProblemDetails"/> 
86+         ///     in the response body. 
87+         /// </returns> 
88+         public  static   async  Task < IActionResult >  ToActionResult ( 
89+             this  Task < Result < Unit > >  resultTask , 
90+             Func < Error ,  ProblemDetails >  onError ) 
91+         { 
92+             return  ( await  resultTask ) . ToActionResult ( onError ) ; 
93+         } 
94+ 
95+         /// <summary> 
96+         ///     Converts a <see cref="Result{TData}"/> to an <see cref="ActionResult{TData}"/>. 
97+         /// </summary> 
98+         /// <typeparam name="TData"> 
99+         ///     The type of data encapsulated by the result. 
100+         /// </typeparam> 
101+         /// <param name="result"> 
102+         ///     The result that this extension method is invoked on. 
103+         /// </param> 
104+         /// <returns> 
105+         ///     If this result is a success then an <see cref="ActionResult{TData}"/> is returned; 
106+         ///     otherwise it is converted to the appropriate 4xx response containing <see cref="ProblemDetails"/> 
107+         ///     in the response body. 
108+         /// </returns> 
109+         public  static   ActionResult < TData >  ToActionResult < TData > ( this  Result < TData >  result ) 
110+         { 
111+             return  result . ToActionResult ( null  as  Func < Error ,  ProblemDetails > ) ; 
112+         } 
113+ 
114+         /// <summary> 
115+         ///     Converts a <see cref="Result{TData}"/> to an <see cref="ActionResult{TData}"/>. 
116+         /// </summary> 
117+         /// <typeparam name="TData"> 
118+         ///     The type of data encapsulated by the result. 
119+         /// </typeparam> 
120+         /// <param name="result"> 
121+         ///     The result that this extension method is invoked on. 
122+         /// </param> 
123+         /// <param name="onError"> 
124+         ///     The function that is invoked if this <paramref name="result"/> is a <see cref="Failure{TData}"/>. 
125+         ///     It is responsible for mapping the <see cref="Error"/> to <see cref="ProblemDetails"/>. 
126+         ///     If this function returns <code>null</code> then the default error mapping conventions are used. 
127+         ///     This therefore provides a way to customize the error mapping from <see cref="Error"/> to <see cref="ProblemDetails"/>. 
128+         /// </param> 
129+         /// <returns> 
130+         ///     If this result is a success then an <see cref="ActionResult{TData}"/> is returned; 
131+         ///     otherwise it is converted to an error response containing <see cref="ProblemDetails"/> 
132+         ///     in the response body. 
133+         /// </returns> 
134+         public  static   ActionResult < TData >  ToActionResult < TData > ( 
135+             this  Result < TData >  result , 
136+             Func < Error ,  ProblemDetails >  onError ) 
137+         { 
138+             return  result . Match ( data =>  new  ActionResult < TData > ( data ) ,  error =>  error . ToActionResult ( onError ) ) ; 
139+         } 
140+ 
141+         /// <summary> 
142+         ///     Asynchronously converts a <see cref="Task{Result}"/> of a <see cref="Result{TData}"/> 
143+         ///     to an <see cref="ActionResult{TData}"/>. 
144+         /// </summary> 
145+         /// <typeparam name="TData"> 
146+         ///     The type of data encapsulated by the result. 
147+         /// </typeparam> 
148+         /// <param name="resultTask"> 
149+         ///     The asynchronous result that this extension method is invoked on. 
150+         /// </param> 
151+         /// <returns> 
152+         ///     If this result is a success then an <see cref="ActionResult{TData}"/> is returned; 
153+         ///     otherwise it is converted to the appropriate 4xx response containing <see cref="ProblemDetails"/> 
154+         ///     in the response body. 
155+         /// </returns> 
156+         public  static   async  Task < ActionResult < TData > >  ToActionResult < TData > ( this  Task < Result < TData > >  resultTask ) 
157+         { 
158+             return  ( await  resultTask ) . ToActionResult ( ) ; 
159+         } 
160+ 
161+         /// <summary> 
162+         ///     Asynchronously converts a <see cref="Task{Result}"/> of a <see cref="Result{TData}"/> 
163+         ///     to an <see cref="ActionResult{TData}"/>. 
164+         /// </summary> 
165+         /// <typeparam name="TData"> 
166+         ///     The type of data encapsulated by the result. 
167+         /// </typeparam> 
168+         /// <param name="resultTask"> 
169+         ///     The asynchronous result that this extension method is invoked on. 
170+         /// </param> 
171+         /// <param name="onError"> 
172+         ///     The function that is invoked if this <paramref name="resultTask"/> is a <see cref="Failure{TData}"/>. 
173+         ///     It is responsible for mapping the <see cref="Error"/> to <see cref="ProblemDetails"/>. 
174+         ///     If this function returns <code>null</code> then the default error mapping conventions are used. 
175+         ///     This therefore provides a way to customize the error mapping from <see cref="Error"/> to <see cref="ProblemDetails"/>. 
176+         /// </param> 
177+         /// <returns> 
178+         ///     If this result is a success then an <see cref="ActionResult{TData}"/> is returned; 
179+         ///     otherwise it is converted to an error response containing <see cref="ProblemDetails"/> 
180+         ///     in the response body. 
181+         /// </returns> 
182+         public  static   async  Task < ActionResult < TData > >  ToActionResult < TData > ( 
183+             this  Task < Result < TData > >  resultTask , 
184+             Func < Error ,  ProblemDetails >  onError ) 
185+         { 
186+             return  ( await  resultTask ) . ToActionResult ( onError ) ; 
187+         } 
188+ 
189+         /// <summary> 
190+         ///     Converts a <see cref="Result{TData}"/> to an <see cref="IActionResult"/>. 
191+         /// </summary> 
192+         /// <typeparam name="TData"> 
193+         ///     The type of data encapsulated by the result. 
194+         /// </typeparam> 
195+         /// <param name="result"> 
196+         ///     The result that this extension method is invoked on. 
197+         /// </param> 
198+         /// <param name="onSuccess"> 
199+         ///     The function that is invoked if this <paramref name="result"/> is a <see cref="Success{TData}"/>. 
200+         ///     It is invoked to map the data to an <see cref="IActionResult"/>. 
201+         /// </param> 
202+         /// <returns> 
203+         ///     If this result is a success the result of <paramref name="onSuccess"/> is returned; 
204+         ///     otherwise it is converted to the appropriate 4xx response containing <see cref="ProblemDetails"/> 
205+         ///     in the response body. 
206+         /// </returns> 
207+         public  static   IActionResult  ToActionResult < TData > ( 
208+             this  Result < TData >  result , 
209+             Func < TData ,  IActionResult >  onSuccess ) 
210+         { 
211+             return  result . ToActionResult ( onSuccess ,  null ) ; 
212+         } 
213+ 
214+         /// <summary> 
215+         ///     Converts a <see cref="Result{TData}"/> to an <see cref="IActionResult"/>. 
216+         /// </summary> 
217+         /// <typeparam name="TData"> 
218+         ///     The type of data encapsulated by the result. 
219+         /// </typeparam> 
220+         /// <param name="result"> 
221+         ///     The result that this extension method is invoked on. 
222+         /// </param> 
223+         /// <param name="onSuccess"> 
224+         ///     The function that is invoked if this <paramref name="result"/> is a <see cref="Success{TData}"/>. 
225+         ///     It is invoked to map the data to an <see cref="IActionResult"/>. 
226+         /// </param> 
227+         /// <param name="onError"> 
228+         ///     The function that is invoked if this <paramref name="result"/> is a <see cref="Failure{TData}"/>. 
229+         ///     It is invoked to map the <see cref="Error"/> to <see cref="ProblemDetails"/>. 
230+         ///     If this function returns <code>null</code> then the default error mapping conventions are used. 
231+         ///     This therefore provides a way to customize the error mapping from <see cref="Error"/> to <see cref="ProblemDetails"/>. 
232+         /// </param> 
233+         /// <returns> 
234+         ///     If this result is a success the result of <paramref name="onSuccess"/> is returned; 
235+         ///     otherwise it is converted to an error response containing <see cref="ProblemDetails"/> 
236+         ///     in the response body. 
237+         /// </returns> 
238+         public  static   IActionResult  ToActionResult < TData > ( 
239+             this  Result < TData >  result , 
240+             Func < TData ,  IActionResult >  onSuccess , 
241+             Func < Error ,  ProblemDetails >  onError ) 
242+         { 
243+             return  result . Match ( onSuccess ,  error =>  error . ToActionResult ( onError ) ) ; 
244+         } 
245+ 
246+         /// <summary> 
247+         ///     Asynchronously converts a <see cref="Task{Result}"/> of a <see cref="Result{TData}"/> 
248+         ///     to an <see cref="IActionResult"/>. 
249+         /// </summary> 
250+         /// <typeparam name="TData"> 
251+         ///     The type of data encapsulated by the result. 
252+         /// </typeparam> 
253+         /// <param name="resultTask"> 
254+         ///     The asynchronous result that this extension method is invoked on. 
255+         /// </param> 
256+         /// <param name="onSuccess"> 
257+         ///     The function that is invoked if this <paramref name="resultTask"/> is a <see cref="Success{TData}"/>. 
258+         ///     It is invoked to map the data to an <see cref="IActionResult"/>. 
259+         /// </param> 
260+         /// <returns> 
261+         ///     If this result is a success the result of <paramref name="onSuccess"/> is returned; 
262+         ///     otherwise it is converted to the appropriate 4xx response containing <see cref="ProblemDetails"/> 
263+         ///     in the response body. 
264+         /// </returns> 
265+         public  static   async  Task < IActionResult >  ToActionResult < TData > ( 
266+             this  Task < Result < TData > >  resultTask , 
267+             Func < TData ,  IActionResult >  onSuccess ) 
268+         { 
269+             return  ( await  resultTask ) . ToActionResult ( onSuccess ) ; 
270+         } 
271+ 
272+         /// <summary> 
273+         ///     Asynchronously converts a <see cref="Task{Result}"/> of a <see cref="Result{TData}"/> 
274+         ///     to an <see cref="IActionResult"/>. 
275+         /// </summary> 
276+         /// <typeparam name="TData"> 
277+         ///     The type of data encapsulated by the result. 
278+         /// </typeparam> 
279+         /// <param name="resultTask"> 
280+         ///     The asynchronous result that this extension method is invoked on. 
281+         /// </param> 
282+         /// <param name="onSuccess"> 
283+         ///     The function that is invoked if this <paramref name="resultTask"/> is a <see cref="Success{TData}"/>. 
284+         ///     It is invoked to map the data to an <see cref="IActionResult"/>. 
285+         /// </param> 
286+         /// <param name="onError"> 
287+         ///     The function that is invoked if this <paramref name="resultTask"/> is a <see cref="Failure{TData}"/>. 
288+         ///     It is invoked to map the <see cref="Error"/> to <see cref="ProblemDetails"/>. 
289+         ///     If this function returns <code>null</code> then the default error mapping conventions are used. 
290+         ///     This therefore provides a way to customize the error mapping from <see cref="Error"/> to <see cref="ProblemDetails"/>. 
291+         /// </param> 
292+         /// <returns> 
293+         ///     If this result is a success the result of <paramref name="onSuccess"/> is returned; 
294+         ///     otherwise it is converted to an error response containing <see cref="ProblemDetails"/> 
295+         ///     in the response body. 
296+         /// </returns> 
297+         public  static   async  Task < IActionResult >  ToActionResult < TData > ( 
298+             this  Task < Result < TData > >  resultTask , 
299+             Func < TData ,  IActionResult >  onSuccess , 
300+             Func < Error ,  ProblemDetails >  onError ) 
301+         { 
302+             return  ( await  resultTask ) . ToActionResult ( onSuccess ,  onError ) ; 
303+         } 
304+     } 
305+ } 
0 commit comments