🌸
🌟
🎀
       /l、
     (゚、 。 7
      l  ~ヽ
      じしf_,)ノ
     /\_/\  
    ( o.o ) 
     > ^ <
/ᐠ。ꞈ。ᐟ\
     ∧,,,∧
    ( ´・ω・)
    (っ✿≧▽≦)
ฅ^•ﻌ•^ฅ
				⠀⠀⠀⠀⢀⡠⠤⠔⢲⢶⡖⠒⠤⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀
				⠀⠀⣠⡚⠁⢀⠀⠀⢄⢻⣿⠀⠀⠀⡙⣷⢤⡀⠀⠀⠀⠀⠀⠀
				⠀⡜⢱⣇⠀⣧⢣⡀⠀⡀⢻⡇⠀⡄⢰⣿⣷⡌⣢⡀⠀⠀⠀⠀
				⠸⡇⡎⡿⣆⠹⣷⡹⣄⠙⣽⣿⢸⣧⣼⣿⣿⣿⣶⣼⣆⠀⠀⠀
				⣷⡇⣷⡇⢹⢳⡽⣿⡽⣷⡜⣿⣾⢸⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀
				⣿⡇⡿⣿⠀⠣⠹⣾⣿⣮⠿⣞⣿⢸⣿⣛⢿⣿⡟⠯⠉⠙⠛⠓
				⣿⣇⣷⠙⡇⠀⠁⠀⠉⣽⣷⣾⢿⢸⣿⠀⢸⣿⢿⠀⠀⠀⠀⠀
				⡟⢿⣿⣷⣾⣆⠀⠀⠘⠘⠿⠛⢸⣼⣿⢖⣼⣿⠘⡆⠀⠀⠀⠀
				⠃⢸⣿⣿⡘⠋⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⡆⠇⠀⠀⠀⠀
				⠀⢸⡿⣿⣇⠀⠈⠀⠤⠀⠀⢀⣿⣿⣿⣿⣿⣿⣧⢸⠀⠀⠀⠀
				⠀⠈⡇⣿⣿⣷⣤⣀⠀⣀⠔⠋⣿⣿⣿⣿⣿⡟⣿⡞⡄⠀⠀⠀
				⠀⠀⢿⢸⣿⣿⣿⣿⣿⡇⠀⢠⣿⡏⢿⣿⣿⡇⢸⣇⠇⠀⠀⠀
				⠀⠀⢸⡏⣿⣿⣿⠟⠋⣀⠠⣾⣿⠡⠀⢉⢟⠷⢼⣿⣿⠀⠀⠀
				⠀⠀⠈⣷⡏⡱⠁⠀⠊⠀⠀⣿⣏⣀⡠⢣⠃⠀⠀⢹⣿⡄⠀⠀
				⠀⠀⠘⢼⣿⠀⢠⣤⣀⠉⣹⡿⠀⠁⠀⡸⠀⠀⠀⠈⣿⡇⠀⠀

ResultSharp

Офтоп

ResultSharp - это моя первая библиотека и мой первый вклад в Open Source. Хотя идея, и следовательно реализация, не очень сложная, но делать библиотеку было интересно. Я научился работать с нугет пакетами, написал пайплайн для автоматического увеличения PATH версии и деплоя на NuGet (это моя отдельная городость).

Я уже успел использовать библиотеку на практике, и мне понравилось писать в функциональном стиле, выстраивая цепочки из Then’ов, получая элегантный и читаемый код. Надеюсь, этот проект будет полезен еще кому-то.

Ссылки

Возможности

  • Удобное представление успешных (Success) и неуспешных (Failure) результатов
  • Композиция и трансформация результатов с помощью функциональных методов (Map, Then, Match и др.)
  • Исключение необходимости использовать try-catch в бизнес-логике
  • Поддержка асинхронных операций
  • Поддержка логгирования: Microsoft.Extensions.Logging, Serilog или любой другой кастомный адаптер

Быстрый старт

Установка

dotnet add package 4q-dev.ResultSharp

Базовое использование

using ResultSharp;
using ResultSharp.Errors;
using ResultSharp.Extensions.FunctionalExtensions.Sync;

Result<int> ParseNumber(string input)
{
    return int.TryParse(input, out var number)
        ? number
        : Error.Failure("Invalid number");
}

int result = ParseNumber("42")
    .Map(n => n * 2)
    .Match(
        ok => Console.Write($"Success: {ok}"), // output: Success: 84
        error => Console.Write($"Error: {error}")
    )
    .UnwrapOrDefault(@default: 0);

Console.WriteLine(result); // 84

Пример использования

Без использования Result:

var user = userRepository.Get();
if (user is null)
{
    logger.LogMessage("User not found");
    throw new Exception("User not found");
}

if (user.Email.IsConfirmed is false)
{
    logger.LogMessage("Email address must be confirmed before sending notifications.");
    throw new Exception("Email address must be confirmed before sending notifications.");
}

try
{
    emailNotificationService.Notify(user.Email, "some notification message");
}
catch (Exception ex)
{
    Logger.LogMessage("Error message: {ex}", ex.Message);
    throw ex;
}

С использованием ResultSharp:

return userRepository.Get()
    .Ensure(user => user.Email.IsConfirmed, onFailure: Error.Unauthorized("Email address must be confirmed before sending notifications."))
    .Then(user => emailNotificationService.Notify(user.Email, "some notification message"))
    .LogIfFailure();

Контрибуция

Мы приветствуем вклад в развитие библиотеки! Чтобы внести изменения:

  1. Форкните репозиторий
  2. Создайте новую ветку (git checkout -b feature-branch)
  3. Внесите изменения и закоммитьте их (git commit -m 'Добавлена новая функция')
  4. Отправьте изменения (git push origin feature-branch)
  5. Откройте Pull Request

Лицензия

Проект распространяется под лицензией MIT. См. файл LICENSE для деталей.