Skip to content

Commit

Permalink
results
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasteles committed May 23, 2023
1 parent 69177a3 commit 84b59ff
Show file tree
Hide file tree
Showing 7 changed files with 662 additions and 2 deletions.
10 changes: 10 additions & 0 deletions src/EnumerablePlus/LinqArrayExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,14 @@ public static TSource[] OrderArray<TSource>(this TSource[] @this)
static Comparison<TSource> KeyComparison<TSource, TKey>(Func<TSource, TKey> key)
where TKey : IComparable<TKey> =>
(x, y) => Comparer<TKey>.Default.Compare(key(x), key(y));


/// <summary>
/// Creates an IEnumerable from an IEnumerator
/// </summary>
public static IEnumerable<T> ToEnumerable<T>(this IEnumerator<T> enumerator)
{
while (enumerator.MoveNext())
yield return enumerator.Current;
}
}
1 change: 0 additions & 1 deletion src/RangeExtension.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;

/// <summary>
Expand Down
118 changes: 118 additions & 0 deletions src/Result/Json/ResultJsonTypeConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using System;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace CSharpPlus.Result.Json;

/// <inheritdoc />
public class ResultJsonConverterFactory : JsonConverterFactory
{
/// <inheritdoc />
public override bool CanConvert(Type typeToConvert) =>
typeToConvert.IsGenericType &&
typeToConvert.GetGenericTypeDefinition() == typeof(Result<,>);

/// <inheritdoc />
public override JsonConverter? CreateConverter(
Type typeToConvert,
JsonSerializerOptions options)
{
var okType = typeToConvert.GetGenericArguments()[0];
var errorType = typeToConvert.GetGenericArguments()[1];

return Activator.CreateInstance(
typeof(ResultJsonConverter<,>).MakeGenericType(okType, errorType),
BindingFlags.Instance | BindingFlags.Public,
binder: null,
args: new object[]
{
options,
},
culture: null) as JsonConverter;
}
}

/// <inheritdoc />
public class ResultJsonConverter<TOk, TError> : JsonConverter<Result<TOk, TError>>
where TError : notnull
{
readonly JsonConverter<TOk> okConverter;
readonly JsonConverter<TError> errorConverter;
readonly Type okType = typeof(TOk);
readonly Type errorType = typeof(TError);

const string propertyStatusName = "status";
const string propertyValueName = "value";
const string statusOk = "ok";
const string statusError = "error";

/// <inheritdoc />
public ResultJsonConverter(JsonSerializerOptions options)
{
okConverter = (JsonConverter<TOk>)options.GetConverter(okType);
errorConverter = (JsonConverter<TError>)options.GetConverter(errorType);
}

/// <inheritdoc />
public override Result<TOk, TError> Read(
ref Utf8JsonReader reader, Type typeToConvert,
JsonSerializerOptions options)
{
var json = JsonElement.ParseValue(ref reader);

if (!json.TryGetProperty(options.PropertyNamingPolicy?.ConvertName(propertyStatusName) ??
propertyStatusName, out var status))
throw new JsonException("Invalid status property");
if (!json.TryGetProperty(options.PropertyNamingPolicy?.ConvertName(propertyValueName) ??
propertyValueName, out var value))
throw new JsonException("Invalid value property");

Utf8JsonReader valueReader = new(JsonSerializer.SerializeToUtf8Bytes(value));
valueReader.Read();
if (status.GetString() == statusOk)
return new Result<TOk, TError>(
okConverter.Read(ref valueReader, okType, options)!);

if (status.GetString() == statusError)
return new Result<TOk, TError>(
errorConverter.Read(ref valueReader, errorType, options)!);

throw new JsonException($"Invalid status {status}");
}

/// <inheritdoc />
public override void Write(
Utf8JsonWriter writer, Result<TOk, TError> value,
JsonSerializerOptions options)
{
writer.WriteStartObject();

if (value.IsOk)
{
writer.WritePropertyName
(options.PropertyNamingPolicy?.ConvertName(propertyStatusName) ??
propertyStatusName);
writer.WriteStringValue(statusOk);

writer.WritePropertyName
(options.PropertyNamingPolicy?.ConvertName(propertyValueName) ??
propertyValueName);
okConverter.Write(writer, value.OkValue, options);
}
else
{
writer.WritePropertyName
(options.PropertyNamingPolicy?.ConvertName(propertyStatusName) ??
propertyStatusName);
writer.WriteStringValue(statusError);

writer.WritePropertyName
(options.PropertyNamingPolicy?.ConvertName(propertyValueName) ??
propertyValueName);
errorConverter.Write(writer, value.ErrorValue, options);
}

writer.WriteEndObject();
}
}

0 comments on commit 84b59ff

Please sign in to comment.