Skip to content

Commit

Permalink
Initial implementations of the library
Browse files Browse the repository at this point in the history
  • Loading branch information
tsutomi committed Jul 2, 2024
1 parent db4abba commit f62226e
Show file tree
Hide file tree
Showing 18 changed files with 1,113 additions and 0 deletions.
77 changes: 77 additions & 0 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Library Release

on:
push:
branches:
- main

permissions:
contents: read
packages: write

jobs:
build:
name: Build and Test
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
dotnet-version: [6.0.x,7.0.x,8.0.x]

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Setup .NET ${{ matrix.dotnet-version }}
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ matrix.dotnet-version }}

- name: Install Dependencies
run: dotnet restore

- name: Build
run: dotnet build --configuration Release --no-restore --nologo

- name: Test
run: dotnet test --configuration Release --no-build --no-restore --verbosity normal

publish:
name: Publish Package
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x

- name: Install Dependencies
run: dotnet restore

- name: Setup GitFlow
uses: gittools/actions/gitversion/setup@v1.1.1
with:
versionSpec: '5.x'

- name: Determine Version
uses: gittools/actions/gitversion/execute@v1.1.1

- name: Build
run: dotnet build -c Release --no-restore /p:Version="${{ env.GitVersion_SemVer }}-alpha.${{ env.GitVersion_PreReleaseTag }}" /p:AssemblyVersion="${{ env.GitVersion_SemVer }}" /p:FileVersion="${{ env.GitVersion_SemVer }}"

- name: Pack the Nuget Packages
run: dotnet pack -c Release --no-build --no-restore --include-symbols --include-source --output nupkgs /p:PackageVersion="${{ env.GitVersion_SemVer }}-alpha.${{ env.GitVersion_PreReleaseTag }}"

- name: Publish the Nuget Packages to the GitHub Package Registry
run: dotnet nuget push **/*.nupkg --skip-duplicate --api-key ${{ secrets.GITHUB_TOKEN }} --source "https://nuget.pkg.github.com/deveel/index.json"

clean:
name: Clean Pre-Release Packages
needs: publish
uses: ./.github/workflows/clean-packages.yml
17 changes: 17 additions & 0 deletions .github/workflows/clean-packages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Clean Pre-Release Packages

on:
workflow_call:
workflow_dispatch:

jobs:
clean:
runs-on: ubuntu-latest
steps:
- name: Clean Deveel.Results
uses: actions/delete-package-versions@v5
with:
package-name: 'Deveel.Results'
package-type: 'nuget'
min-versions-to-keep: 10
delete-only-pre-release-versions: true
30 changes: 30 additions & 0 deletions .github/workflows/pr-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: PR Build

on:
pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
dotnet-version: [6.0.x, 7.0.x, 8.0.x]

steps:
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ matrix.dotnet-version }}

- name: Install dependencies
run: dotnet restore

- name: Build
run: dotnet build -c Release --no-restore

- name: Test
run: dotnet test -c Release --no-build --no-restore
36 changes: 36 additions & 0 deletions Deveel.Results.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A23FC229-2F71-4F53-BAFE-62C05D1B85F2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Deveel.Results", "src\Deveel.Results\Deveel.Results.csproj", "{AF4AA20C-ABEE-41C3-B7FA-660001B3273C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{09824D71-F662-4403-A251-CB5E064CC019}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deveel.Results.XUnit", "test\Deveel.Results.XUnit\Deveel.Results.XUnit.csproj", "{0B0F8D70-20EC-4B29-8AD3-64047EF50975}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AF4AA20C-ABEE-41C3-B7FA-660001B3273C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF4AA20C-ABEE-41C3-B7FA-660001B3273C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF4AA20C-ABEE-41C3-B7FA-660001B3273C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF4AA20C-ABEE-41C3-B7FA-660001B3273C}.Release|Any CPU.Build.0 = Release|Any CPU
{0B0F8D70-20EC-4B29-8AD3-64047EF50975}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B0F8D70-20EC-4B29-8AD3-64047EF50975}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0B0F8D70-20EC-4B29-8AD3-64047EF50975}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B0F8D70-20EC-4B29-8AD3-64047EF50975}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{AF4AA20C-ABEE-41C3-B7FA-660001B3273C} = {A23FC229-2F71-4F53-BAFE-62C05D1B85F2}
{0B0F8D70-20EC-4B29-8AD3-64047EF50975} = {09824D71-F662-4403-A251-CB5E064CC019}
EndGlobalSection
EndGlobal
17 changes: 17 additions & 0 deletions src/Deveel.Results/Deveel.Results.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>Deveel</RootNamespace>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<PropertyGroup>
<Title>Deveel Results</Title>
<Description>A simple and unambitious library to implement the result pattern in services.</Description>
<PackageTags>result;results;operation;pattern;error;domain;ddd;domain-driven</PackageTags>
</PropertyGroup>

</Project>
30 changes: 30 additions & 0 deletions src/Deveel.Results/IOperationError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace Deveel
{
/// <summary>
/// Represents an error that occurred during an operation.
/// </summary>
public interface IOperationError
{
/// <summary>
/// Gets the unique code of the error
/// within the domain of the operation.
/// </summary>
string Code { get; }

/// <summary>
/// Gets the domain of the operation
/// where the error occurred.
/// </summary>
string Domain { get; }

/// <summary>
/// Gets the message that describes the error.
/// </summary>
string? Message { get; }

/// <summary>
/// Gets an inner error that caused this error.
/// </summary>
IOperationError? InnerError { get; }
}
}
19 changes: 19 additions & 0 deletions src/Deveel.Results/IOperationResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Deveel
{
/// <summary>
/// Represents the result of an operation.
/// </summary>
public interface IOperationResult
{
/// <summary>
/// Gets the type of the result of the operation.
/// </summary>
OperationResultType ResultType { get; }

/// <summary>
/// When the result is a failure, gets the error
/// that caused the operation to fail.
/// </summary>
IOperationError? Error { get; }
}
}
15 changes: 15 additions & 0 deletions src/Deveel.Results/IOperationResult_T.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Deveel
{
/// <summary>
/// Represents the result of an operation that
/// has a value returned.
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IOperationResult<T> : IOperationResult
{
/// <summary>
/// Gets the value returned by an operation.
/// </summary>
T? Value { get; }
}
}
52 changes: 52 additions & 0 deletions src/Deveel.Results/OperationError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace Deveel
{
/// <summary>
/// Implements a simple error object that can be used to represent
/// a failure in an operation.
/// </summary>
public readonly struct OperationError : IOperationError
{
/// <summary>
/// Constructs an instance of an <see cref="OperationError"/> object.
/// </summary>
/// <param name="code">
/// The code of the error, that is unique within the
/// given domain.
/// </param>
/// <param name="domain">
/// The domain where the error occurred.
/// </param>
/// <param name="message">
/// A message that describes the error.
/// </param>
/// <param name="innerError">
/// A reference to an inner error that caused this error.
/// </param>
/// <exception cref="ArgumentNullException">
/// Thrown when the <paramref name="code"/> or <paramref name="domain"/>
/// are <see langword="null"/>.
/// </exception>
public OperationError(string code, string domain, string? message = null, IOperationError? innerError = null)
{
ArgumentNullException.ThrowIfNull(code, nameof(code));
ArgumentNullException.ThrowIfNull(domain, nameof(domain));

Code = code;
Domain = domain;
Message = message;
InnerError = innerError;
}

/// <inheritdoc />
public string Code { get; }

/// <inheritdoc />
public string Domain { get; }

/// <inheritdoc />
public string? Message { get; }

/// <inheritdoc />
public IOperationError? InnerError { get; }
}
}
96 changes: 96 additions & 0 deletions src/Deveel.Results/OperationException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Non-nullable field must contain a non-null value when exiting constructor.
#pragma warning disable CS8618

namespace Deveel
{
/// <summary>
/// An exception that represents an unhandled error that has
/// occurred during an operation.
/// </summary>
public class OperationException : Exception, IOperationError
{
/// <summary>
/// Constructs an instance of an <see cref="OperationException"/> with
/// the specified error code and domain.
/// </summary>
/// <param name="errorCode">
/// The unique code that identifies the error within the domain.
/// </param>
/// <param name="errorDomain">
/// The domain where the error has occurred.
/// </param>
public OperationException(string errorCode, string errorDomain)
{
SetErrorDetails(errorCode, errorDomain);
}

/// <summary>
/// Constructs an instance of an <see cref="OperationException"/> with
/// the specified error code and domain.
/// </summary>
/// <param name="errorCode">
/// The unique code that identifies the error within the domain.
/// </param>
/// <param name="errorDomain">
/// The domain where the error has occurred.
/// </param>
/// <param name="message">
/// A message that describes the error.
/// </param>
public OperationException(string errorCode, string errorDomain, string? message)
: base(message)
{
SetErrorDetails(errorCode, errorDomain);
}

/// <summary>
/// Constructs an instance of an <see cref="OperationException"/> with
/// the specified error code and domain.
/// </summary>
/// <param name="errorCode">
/// The unique code that identifies the error within the domain.
/// </param>
/// <param name="errorDomain">
/// The domain where the error has occurred.
/// </param>
/// <param name="message">
/// A message that describes the error.
/// </param>
/// <param name="innerException">
/// An exception that has caused the error.
/// </param>
public OperationException(string errorCode, string errorDomain, string? message, Exception? innerException)
: base(message, innerException)
{
SetErrorDetails(errorCode, errorDomain);
}

/// <summary>
/// The unique code that identifies the error within the domain.
/// </summary>
public string ErrorCode { get; private set; }

string IOperationError.Code => ErrorCode;

/// <summary>
/// The domain where the error has occurred.
/// </summary>
public string ErrorDomain { get; private set; }

string IOperationError.Domain => ErrorDomain;

IOperationError? IOperationError.InnerError => InnerException as IOperationError;

private void SetErrorDetails(string errorCode, string errorDomain)
{
ArgumentNullException.ThrowIfNull(errorCode, nameof(errorCode));
ArgumentNullException.ThrowIfNull(errorDomain, nameof(errorDomain));

ErrorCode = errorCode;
ErrorDomain = errorDomain;

Data[nameof(ErrorCode)] = errorCode;
Data[nameof(ErrorDomain)] = errorDomain;
}
}
}
Loading

0 comments on commit f62226e

Please sign in to comment.