using CsharpFp3.Library; using static CsharpFp3.Library.ResultModule; namespace CsharpFp3.Domain; public sealed record Account(Guid Id, Money Balance); public abstract record AccountError { public sealed record OpeningBalanceMustBeNonNegative : AccountError; public sealed record AmountMustBePositive : AccountError; public sealed record InsufficientBalance(Money Balance, Money Amount) : AccountError; public sealed record AccountNotFound(Guid AccountId) : AccountError; } public static class AccountDomain { public static Result Open(Guid id, Money openingBalance) => openingBalance.Amount < 0m ? Fail(new AccountError.OpeningBalanceMustBeNonNegative()) : Ok(new Account(id, openingBalance)); public static Result Withdraw(Account account, Money amount) => (account.Balance.Amount, amount.Amount) switch { (_, <= 0m) => Fail(new AccountError.AmountMustBePositive()), var (balance, transaction) when balance < transaction => Fail( new AccountError.InsufficientBalance(account.Balance, amount) ), var (balance, transaction) => Ok( account with { Balance = new Money(balance - transaction), } ), }; }