Skip to content

Commit

Permalink
Improved performance. (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
jscarle authored Feb 27, 2024
1 parent c5d7f11 commit ea64bb4
Show file tree
Hide file tree
Showing 20 changed files with 786 additions and 824 deletions.
47 changes: 0 additions & 47 deletions src/LightResults/Common/ErrorArray.cs

This file was deleted.

97 changes: 0 additions & 97 deletions src/LightResults/Common/ResultBase.cs

This file was deleted.

117 changes: 117 additions & 0 deletions src/LightResults/Common/StringHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using System.Collections.Immutable;

namespace LightResults.Common;

internal static class StringHelper
{
public static string GetResultString(string typeName, string successString, string informationString)
{
const string preResultStr = " { IsSuccess = ";
const string postResultStr = " }";
#if NET6_0_OR_GREATER
var stringLength = typeName.Length + preResultStr.Length + successString.Length + informationString.Length + postResultStr.Length;

var str = string.Create(stringLength, (typeName, successString, informationString), (span, state) => { span.TryWrite($"{state.typeName}{preResultStr}{state.successString}{state.informationString}{postResultStr}", out _); });

return str;
#else
return $"{typeName}{preResultStr}{successString}{informationString}{postResultStr}";
#endif
}

public static string GetResultValueString<T>(T value)
{
var valueString = value?.ToString() ?? "";

const string preValueStr = ", Value = ";
const string charStr = "'";
const string stringStr = "\"";

if (value is bool || value is sbyte || value is byte || value is short || value is ushort || value is int || value is uint || value is long || value is ulong ||
#if NET7_0_OR_GREATER
value is Int128 || value is UInt128 ||
#endif
value is decimal || value is float || value is double)
{
#if NET6_0_OR_GREATER
var stringLength = preValueStr.Length + valueString.Length;

var str = string.Create(stringLength, valueString, (span, state) => { span.TryWrite($"{preValueStr}{state}", out _); });

return str;
#else
return $"{preValueStr}{valueString}";
#endif
}

if (value is char)
{
#if NET6_0_OR_GREATER
var stringLength = preValueStr.Length + charStr.Length + valueString.Length + charStr.Length;

var str = string.Create(stringLength, valueString, (span, state) => { span.TryWrite($"{preValueStr}{charStr}{state}{charStr}", out _); });

return str;
#else
return $"{preValueStr}{charStr}{valueString}{charStr}";
#endif
}

if (value is string)
{
#if NET6_0_OR_GREATER
var stringLength = preValueStr.Length + stringStr.Length + valueString.Length + stringStr.Length;

var str = string.Create(stringLength, valueString, (span, state) => { span.TryWrite($"{preValueStr}{stringStr}{state}{stringStr}", out _); });

return str;
#else
return $"{preValueStr}{stringStr}{valueString}{stringStr}";
#endif
}

return "";
}

public static string GetResultErrorString(ImmutableArray<IError> errors)
{
if (errors[0].Message.Length <= 0)
return "";

var errorMessage = errors[0].Message;

const string preErrorStr = ", Error = \"";
const string postErrorStr = "\"";
#if NET6_0_OR_GREATER
var stringLength = preErrorStr.Length + errorMessage.Length + postErrorStr.Length;

var str = string.Create(stringLength, errorMessage, (span, state) => { span.TryWrite($"{preErrorStr}{state}{postErrorStr}", out _); });

return str;
#else
return $"{preErrorStr}{errorMessage}{postErrorStr}";
#endif
}

public static string GetErrorString(IError error)
{
var errorType = error.GetType().Name;

if (error.Message.Length <= 0)
return errorType;

var errorMessage = error.Message;

const string preErrorStr = " { Message = \"";
const string postErrorStr = "\" }";
#if NET6_0_OR_GREATER
var stringLength = errorType.Length + preErrorStr.Length + errorMessage.Length + postErrorStr.Length;

var str = string.Create(stringLength, (errorType, errorMessage), (span, state) => { span.TryWrite($"{state.errorType}{preErrorStr}{state.errorMessage}{postErrorStr}", out _); });

return str;
#else
return $"{errorType}{preErrorStr}{errorMessage}{postErrorStr}";
#endif
}
}
36 changes: 36 additions & 0 deletions src/LightResults/Compiler/CompilerServices.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;

// ReSharper disable CheckNamespace

namespace System.Runtime.CompilerServices
{
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal static class IsExternalInit;

[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Field | AttributeTargets.Property, Inherited = false)]
internal sealed class RequiredMemberAttribute : Attribute;

[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
internal sealed class CompilerFeatureRequiredAttribute(string featureName) : Attribute
{
public const string RefStructs = nameof(RefStructs);
public const string RequiredMembers = nameof(RequiredMembers);
public string FeatureName { get; } = featureName;

public bool IsOptional { get; init; }
}
}

namespace System.Diagnostics.CodeAnalysis
{
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
[AttributeUsage(AttributeTargets.Constructor)]
internal sealed class SetsRequiredMembersAttribute : Attribute;
}
10 changes: 4 additions & 6 deletions src/LightResults/Error.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

#else
using System.Collections.Immutable;

#endif
using LightResults.Common;

namespace LightResults;

/// <summary>Represents an error with a message and associated metadata.</summary>
Expand Down Expand Up @@ -86,9 +87,6 @@ public Error(string message, IDictionary<string, object> metadata)
/// <inheritdoc />
public override string ToString()
{
if (Message.Length > 0)
return Message;

return base.ToString() ?? "";
return StringHelper.GetErrorString(this);
}
}
}
10 changes: 8 additions & 2 deletions src/LightResults/IResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ public interface IResult

/// <summary>Gets a collection of errors associated with the result.</summary>
/// <returns>An <see cref="IReadOnlyCollection{T}" /> of <see cref="IError" /> representing the errors.</returns>
IReadOnlyList<IError> Errors { get; }
IReadOnlyCollection<IError> Errors { get; }

/// <summary>Gets the error of the result, throwing an exception if the result is successful.</summary>
/// <returns>The error of the result.</returns>
/// <exception cref="InvalidOperationException">Thrown when attempting to get or set the value of a failed result.</exception>
IError Error { get; }

/// <summary>Checks if the result contains an error of the specific type.</summary>
/// <typeparam name="TError">The type of error to check for.</typeparam>
Expand All @@ -25,6 +30,7 @@ public interface IResult
public interface IResult<out TValue> : IResult
{
/// <summary>Gets the value of the result, throwing an exception if the result is failed.</summary>
/// <returns>The value of the result.</returns>
/// <exception cref="InvalidOperationException">Thrown when attempting to get or set the value of a failed result.</exception>
public TValue Value { get; }
}
}
Loading

0 comments on commit ea64bb4

Please sign in to comment.