Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved performance. #12

Merged
merged 1 commit into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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