|
1 | | -<!-- Improved compatibility of back to top link: See: https://github.com/othneildrew/Best-README-Template/pull/73 --> |
2 | | -<a name="readme-top"></a> |
3 | | - |
4 | | -<!-- PROJECT SHIELDS --> |
5 | | -<!-- |
6 | | -*** I'm using markdown "reference style" links for readability. |
7 | | -*** Reference links are enclosed in brackets [ ] instead of parentheses ( ). |
8 | | -*** See the bottom of this document for the declaration of the reference variables |
9 | | -*** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use. |
10 | | -*** https://www.markdownguide.org/basic-syntax/#reference-style-links |
11 | | ---> |
12 | | -[](https://dotnet-elements.felixstrauss.dev/) |
13 | | - |
14 | | -<!-- PROJECT LOGO --> |
15 | | -<br /> |
16 | | -<div align="center"> |
17 | | - <a href="https://github.com/Felix-CodingClimber/DotNetElements"> |
18 | | - <img src="brand/Logo.png" alt="Logo" width="424" height="123"> |
19 | | - </a> |
20 | | - |
21 | | -<h3 align="center">DotNet Elements</h3> |
22 | | - |
23 | | - <p align="center"> |
24 | | - Opinionated framework to build .NET applications fast and easy while focusing more on the final product and less on writing low-level code. |
25 | | - <br /> |
26 | | - <a href="https://dotnet-elements.felixstrauss.dev/"><strong>Explore the docs »</strong></a> |
27 | | - <br /> |
28 | | - <br /> |
29 | | - <!-- |
30 | | - <a href="https://github.com/Felix-CodingClimber/DotNetElements">View Demo</a> |
31 | | - · |
32 | | - --> |
33 | | - <a href="https://github.com/Felix-CodingClimber/DotNetElements/issues">Report Bug</a> |
34 | | - · |
35 | | - <a href="https://github.com/Felix-CodingClimber/DotNetElements/issues">Request Feature</a> |
36 | | - </p> |
37 | | -</div> |
38 | | - |
39 | | - |
40 | | - |
41 | | -<!-- TABLE OF CONTENTS --> |
42 | | -<details> |
43 | | - <summary>Table of Contents</summary> |
44 | | - <ol> |
45 | | - <li> |
46 | | - <a href="#about-the-project">About The Project</a> |
47 | | - <ul> |
48 | | - <li><a href="#built-with">Built With</a></li> |
49 | | - </ul> |
50 | | - </li> |
51 | | - <!-- |
52 | | - <li> |
53 | | - <a href="#getting-started">Getting Started</a> |
54 | | - <ul> |
55 | | - <li><a href="#prerequisites">Prerequisites</a></li> |
56 | | - <li><a href="#installation">Installation</a></li> |
57 | | - </ul> |
58 | | - </li> |
59 | | - <li><a href="#usage">Usage</a></li> |
60 | | - <li><a href="#roadmap">Roadmap</a></li> |
61 | | - <li><a href="#contributing">Contributing</a></li> |
62 | | - --> |
63 | | - <li><a href="#license">License</a></li> |
64 | | - <!-- |
65 | | - <li><a href="#contact">Contact</a></li> |
66 | | - <li><a href="#acknowledgments">Acknowledgments</a></li> |
67 | | - --> |
68 | | - </ol> |
69 | | -</details> |
70 | | - |
71 | | - |
72 | | - |
73 | | -<!-- ABOUT THE PROJECT --> |
74 | | -## About The Project |
75 | | -<!-- |
76 | | -[![Product Name Screen Shot][product-screenshot]](https://example.com) |
77 | | ---> |
78 | | -> [!CAUTION] |
79 | | -> Framework is work in progress and not considered production ready (while still used in some personal projects). Feel free to try it out and share your thoughts. |
80 | | -
|
81 | | -<p align="right">(<a href="#readme-top">back to top</a>)</p> |
82 | | - |
83 | | - |
84 | | - |
85 | | -### Built With |
86 | | - |
87 | | -[![NET][.NET]][.NET-url] |
88 | | - |
89 | | -<p align="right">(<a href="#readme-top">back to top</a>)</p> |
90 | | - |
91 | | - |
92 | | - |
93 | | -<!-- GETTING STARTED --> |
94 | | -<!-- |
95 | | -## Getting Started |
96 | | -
|
97 | | -This is an example of how you may give instructions on setting up your project locally. |
98 | | -To get a local copy up and running follow these simple example steps. |
99 | | -
|
100 | | -### Prerequisites |
101 | | -
|
102 | | -This is an example of how to list things you need to use the software and how to install them. |
103 | | -* npm |
104 | | - ```sh |
105 | | - npm install npm@latest -g |
106 | | - ``` |
107 | | -
|
108 | | -### Installation |
109 | | -
|
110 | | -1. Get a free API Key at [https://example.com](https://example.com) |
111 | | -2. Clone the repo |
112 | | - ```sh |
113 | | - git clone https://github.com/github_username/repo_name.git |
114 | | - ``` |
115 | | -3. Install NPM packages |
116 | | - ```sh |
117 | | - npm install |
118 | | - ``` |
119 | | -4. Enter your API in `config.js` |
120 | | - ```js |
121 | | - const API_KEY = 'ENTER YOUR API'; |
122 | | - ``` |
123 | | -
|
124 | | -<p align="right">(<a href="#readme-top">back to top</a>)</p> |
125 | | ---> |
126 | | - |
127 | | - |
128 | | -<!-- USAGE EXAMPLES --> |
129 | | -<!--## Usage |
130 | | -
|
131 | | -Use this space to show useful examples of how a project can be used. Additional screenshots, code examples and demos work well in this space. You may also link to more resources. |
132 | | -
|
133 | | -_For more examples, please refer to the [Documentation](https://example.com)_ |
134 | | -
|
135 | | -<p align="right">(<a href="#readme-top">back to top</a>)</p> |
136 | | ---> |
137 | | - |
138 | | - |
139 | | -<!-- ROADMAP --> |
140 | | -<!-- |
141 | | -## Roadmap |
142 | | -
|
143 | | -- [ ] Feature 1 |
144 | | -- [ ] Feature 2 |
145 | | -- [ ] Feature 3 |
146 | | - - [ ] Nested Feature |
147 | | -
|
148 | | -See the [open issues](https://github.com/github_username/repo_name/issues) for a full list of proposed features (and known issues). |
149 | | -
|
150 | | -<p align="right">(<a href="#readme-top">back to top</a>)</p> |
151 | | ---> |
152 | | - |
153 | | - |
154 | | -<!-- CONTRIBUTING --> |
155 | | -<!-- |
156 | | -## Contributing |
157 | | -
|
158 | | -Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. |
159 | | -
|
160 | | -If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". |
161 | | -Don't forget to give the project a star! Thanks again! |
162 | | -
|
163 | | -1. Fork the Project |
164 | | -2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) |
165 | | -3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) |
166 | | -4. Push to the Branch (`git push origin feature/AmazingFeature`) |
167 | | -5. Open a Pull Request |
168 | | -
|
169 | | -<p align="right">(<a href="#readme-top">back to top</a>)</p> |
170 | | ---> |
171 | | - |
172 | | - |
173 | | -<!-- LICENSE --> |
174 | | -## License |
175 | | - |
176 | | -Distributed under the MIT License. See `LICENSE.txt` for more information. |
177 | | - |
178 | | -<p align="right">(<a href="#readme-top">back to top</a>)</p> |
179 | | - |
180 | | - |
181 | | - |
182 | | -<!-- CONTACT --> |
183 | | -<!-- |
184 | | -## Contact |
185 | | -
|
186 | | -Your Name - [@twitter_handle](https://twitter.com/twitter_handle) - email@email_client.com |
187 | | -
|
188 | | -Project Link: [https://github.com/github_username/repo_name](https://github.com/github_username/repo_name) |
189 | | -
|
190 | | -<p align="right">(<a href="#readme-top">back to top</a>)</p> |
191 | | ---> |
192 | | - |
193 | | - |
194 | | -<!-- ACKNOWLEDGMENTS --> |
195 | | -<!-- |
196 | | -## Acknowledgments |
197 | | -
|
198 | | -* []() |
199 | | -* []() |
200 | | -* []() |
201 | | -
|
202 | | -<p align="right">(<a href="#readme-top">back to top</a>)</p> |
203 | | ---> |
204 | | - |
205 | | - |
206 | | -<!-- MARKDOWN LINKS & IMAGES --> |
207 | | -<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links --> |
208 | | -[.NET]: https://img.shields.io/badge/.NET-000000?style=for-the-badge&logo=dotnet&labelColor=512BD4 |
209 | | -[.NET-url]: https://dotnet.microsoft.com/en-us/ |
210 | | - |
211 | | -<!-- |
212 | | -[contributors-shield]: https://img.shields.io/github/contributors/github_username/repo_name.svg?style=for-the-badge |
213 | | -[contributors-url]: https://github.com/github_username/repo_name/graphs/contributors |
214 | | -[forks-shield]: https://img.shields.io/github/forks/github_username/repo_name.svg?style=for-the-badge |
215 | | -[forks-url]: https://github.com/github_username/repo_name/network/members |
216 | | -[stars-shield]: https://img.shields.io/github/stars/github_username/repo_name.svg?style=for-the-badge |
217 | | -[stars-url]: https://github.com/github_username/repo_name/stargazers |
218 | | -[issues-shield]: https://img.shields.io/github/issues/github_username/repo_name.svg?style=for-the-badge |
219 | | -[issues-url]: https://github.com/github_username/repo_name/issues |
220 | | -[license-shield]: https://img.shields.io/github/license/github_username/repo_name.svg?style=for-the-badge |
221 | | -[license-url]: https://github.com/github_username/repo_name/blob/master/LICENSE.txt |
222 | | -[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555 |
223 | | -[linkedin-url]: https://linkedin.com/in/linkedin_username |
224 | | -[product-screenshot]: images/screenshot.png |
225 | | ---> |
| 1 | +## About |
| 2 | + |
| 3 | +This project provides simple `Result` and `Result<TValue>` types to be used as return types of functions as an alternative to exceptions. |
| 4 | + |
| 5 | +The default types have a .IsOk and .IsFail property to check wether the function returned success or failure. In case of a Result<TValue> the result contains the return value of the function. |
| 6 | + |
| 7 | +To include error state in the Result, one has to implement a custom `ErrorResult<TValue, TError>`. |
| 8 | +A source generator automatically provides the class implementation. |
| 9 | + |
| 10 | +There are helper functions like `Fail()`, `Ok()` or `TryGetValue(out string? resultValue)` to make working with Results as simple as possible. |
| 11 | + |
| 12 | +## Recommended setup |
| 13 | + |
| 14 | +1. Install nuget package `> dotnet add package DotNetElements.Core.Result --version <insert-latest-version-here>` |
| 15 | + |
| 16 | +2. Add the following to a GlobalUsing.cs |
| 17 | +```cs |
| 18 | +global using static DotNetElements.Core.Result.ResultHelper; |
| 19 | +``` |
| 20 | + |
| 21 | +## Usage examples for basic Result and Result<TValue> types |
| 22 | + |
| 23 | +### Example function using a Result as return type |
| 24 | +```cs |
| 25 | +static Result<string> GetResultFunction(bool expectedResult) |
| 26 | +{ |
| 27 | + // With logging |
| 28 | + if (!expectedResult) |
| 29 | + return Fail(() => Console.WriteLine("Fail from method")); |
| 30 | + |
| 31 | + // Without logging |
| 32 | + if (!expectedResult) |
| 33 | + return Fail(); |
| 34 | + |
| 35 | + return "Success from method"; |
| 36 | +} |
| 37 | +``` |
| 38 | + |
| 39 | +### Usage example using the .TryGetValue semantic |
| 40 | +```cs |
| 41 | +if (GetResultFunction(true).TryGetValue(out string? resultValue)) |
| 42 | +{ |
| 43 | + Console.WriteLine($"Success from caller with value <{resultValue}>"); |
| 44 | +} |
| 45 | +else |
| 46 | +{ |
| 47 | + Console.WriteLine("Fail from caller"; |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +### Usage example using manual check and GetValueUnsafe() |
| 52 | +```cs |
| 53 | +Result<string> result = GetResultFunction(false); |
| 54 | + |
| 55 | +if (result.IsOk) |
| 56 | +{ |
| 57 | + Console.WriteLine($"Success from caller with value <{result.GetValueUnsafe()}>"); |
| 58 | +} |
| 59 | +else |
| 60 | +{ |
| 61 | + Console.WriteLine("Fail from caller"); |
| 62 | +} |
| 63 | +``` |
| 64 | + |
| 65 | +### Usage example using explicit conversions to prevent data loss for Result with value |
| 66 | +```cs |
| 67 | +Result resultWithoutValue = result.AsResult(); |
| 68 | +``` |
| 69 | + |
| 70 | +## Usage examples for source generated custom ErrorResult<TError> and ErrorResult<TValue, TError> types |
| 71 | + |
| 72 | +### Define a custom ErrorResult |
| 73 | +```cs |
| 74 | +namespace MyNamespace; |
| 75 | + |
| 76 | +public enum CrudError |
| 77 | +{ |
| 78 | + InternalError, |
| 79 | + NotFound, |
| 80 | + DuplicateEntry |
| 81 | +} |
| 82 | + |
| 83 | +[ErrorResult<CrudError>] |
| 84 | +public partial class CrudResult<TValue>; |
| 85 | +``` |
| 86 | + |
| 87 | +### Example function using a custom CrudResult as return type |
| 88 | +```cs |
| 89 | +// This is needed to enable the usage of Ok() and Fail methods |
| 90 | +// Can be in each file or in a GlobalUsing.cs |
| 91 | +using static MyNamespace.CrudResultHelper; |
| 92 | + |
| 93 | +static CrudResult<string> GetCrudResultFunction(bool expectedResult) |
| 94 | +{ |
| 95 | + // With logging |
| 96 | + if (!expectedResult) |
| 97 | + return Fail(CrudError.InternalError, () => Console.WriteLine("Fail from method")); |
| 98 | + |
| 99 | + // Without logging |
| 100 | + if (!expectedResult) |
| 101 | + return Fail(CrudError.InternalError); |
| 102 | + |
| 103 | + return "Success from method"; |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +### Usage example using the .TryGetValue semantic |
| 108 | +```cs |
| 109 | +if (GetCrudResultFunction(true).TryGetValue(out string? crudValue, out CrudError? error)) |
| 110 | +{ |
| 111 | + Console.WriteLine($"Success from caller with value <{crudValue}>"); |
| 112 | +} |
| 113 | +else |
| 114 | +{ |
| 115 | + Console.WriteLine($"Fail from caller with error <{error}>"); |
| 116 | +} |
| 117 | +``` |
| 118 | + |
| 119 | +### Usage example using manual check and GetValueUnsafe() |
| 120 | +```cs |
| 121 | +CrudResult<string> crudResult = GetCrudResultFunction(false); |
| 122 | + |
| 123 | +if (crudResult.IsOk) |
| 124 | +{ |
| 125 | + Console.WriteLine($"Success from caller with value <{crudResult.GetValueUnsafe()}>"); |
| 126 | +} |
| 127 | +else |
| 128 | +{ |
| 129 | + Console.WriteLine($"Fail from caller with error <{crudResult.GetErrorUnsafe()}>"); |
| 130 | +} |
| 131 | +``` |
| 132 | + |
| 133 | +### Usage example using explicit conversions to prevent data loss |
| 134 | +```cs |
| 135 | +CrudResult crudResultWithoutValue = crudResult.AsCrudResult(); |
| 136 | +Result<string> simpleResultWithValue = crudResult.AsResultWithValue(); |
| 137 | +Result simpleResultWithoutValue = crudResult.AsResult(); |
| 138 | +``` |
0 commit comments