diff --git a/FartingUnicorn.Benchmarks/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Benchmarks.UserProfile.g.cs b/FartingUnicorn.Benchmarks/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Benchmarks.UserProfile.g.cs index c783811..a6e8ce8 100644 --- a/FartingUnicorn.Benchmarks/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Benchmarks.UserProfile.g.cs +++ b/FartingUnicorn.Benchmarks/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Benchmarks.UserProfile.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Benchmarks_UserProfile(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Benchmarks_UserProfile(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Benchmarks.UserProfile(); @@ -24,7 +26,7 @@ public static partial class Mappers var isNamePropertyDefined = jsonElement.TryGetProperty("Name", out var jsonNameProperty); if (isNamePropertyDefined) { - // type = String, isOption = False, isNullable = False + // type = System.String, isOption = False, isNullable = False if (jsonNameProperty.ValueKind == JsonValueKind.Null) { errors.Add(new RequiredValueMissingError([.. path, "Name"])); diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NonNullableNonOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NonNullableNonOptional_Tests.BlogPost.g.cs index 62cfe51..1d75a57 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NonNullableNonOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NonNullableNonOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_BoolType_NonNullableNonOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_BoolType_NonNullableNonOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.BoolType.NonNullableNonOptional_Tests.BlogPost(); @@ -24,7 +26,7 @@ public static partial class Mappers var isIsDraftPropertyDefined = jsonElement.TryGetProperty("IsDraft", out var jsonIsDraftProperty); if (isIsDraftPropertyDefined) { - // type = Boolean, isOption = False, isNullable = False + // type = System.Boolean, isOption = False, isNullable = False if (jsonIsDraftProperty.ValueKind == JsonValueKind.Null) { errors.Add(new RequiredValueMissingError([.. path, "IsDraft"])); diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NonNullableOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NonNullableOptional_Tests.BlogPost.g.cs index ff21f98..b25348f 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NonNullableOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NonNullableOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_BoolType_NonNullableOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_BoolType_NonNullableOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.BoolType.NonNullableOptional_Tests.BlogPost(); @@ -24,10 +26,10 @@ public static partial class Mappers var isIsDraftPropertyDefined = jsonElement.TryGetProperty("IsDraft", out var jsonIsDraftProperty); if (isIsDraftPropertyDefined) { - // type = Boolean, isOption = True, isNullable = False + // type = System.Boolean, isOption = True, isNullable = False if (jsonIsDraftProperty.ValueKind == JsonValueKind.Null) { - obj.IsDraft = new None(); + obj.IsDraft = new None(); } else if (jsonIsDraftProperty.ValueKind == JsonValueKind.True || jsonIsDraftProperty.ValueKind == JsonValueKind.False) { diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NullableNonOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NullableNonOptional_Tests.BlogPost.g.cs index 112bbba..c49eb57 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NullableNonOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NullableNonOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_BoolType_NullableNonOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_BoolType_NullableNonOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.BoolType.NullableNonOptional_Tests.BlogPost(); @@ -24,7 +26,7 @@ public static partial class Mappers var isIsDraftPropertyDefined = jsonElement.TryGetProperty("IsDraft", out var jsonIsDraftProperty); if (isIsDraftPropertyDefined) { - // type = Boolean, isOption = False, isNullable = True + // type = System.Boolean, isOption = False, isNullable = True if (jsonIsDraftProperty.ValueKind == JsonValueKind.Null) { errors.Add(new RequiredValueMissingError([.. path, "IsDraft"])); diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NullableOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NullableOptional_Tests.BlogPost.g.cs index e744a70..e64615c 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NullableOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.BoolType.NullableOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_BoolType_NullableOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_BoolType_NullableOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.BoolType.NullableOptional_Tests.BlogPost(); @@ -24,10 +26,10 @@ public static partial class Mappers var isIsDraftPropertyDefined = jsonElement.TryGetProperty("IsDraft", out var jsonIsDraftProperty); if (isIsDraftPropertyDefined) { - // type = Boolean, isOption = True, isNullable = True + // type = System.Boolean, isOption = True, isNullable = True if (jsonIsDraftProperty.ValueKind == JsonValueKind.Null) { - obj.IsDraft = new None(); + obj.IsDraft = new None(); } else if (jsonIsDraftProperty.ValueKind == JsonValueKind.True || jsonIsDraftProperty.ValueKind == JsonValueKind.False) { diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.EnumType.NonNullableNonOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.EnumType.NonNullableNonOptional_Tests.BlogPost.g.cs new file mode 100644 index 0000000..b74d715 --- /dev/null +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.EnumType.NonNullableNonOptional_Tests.BlogPost.g.cs @@ -0,0 +1,68 @@ +using DotNetThoughts.Results; +using System.Text.Json; +using static FartingUnicorn.MapperOptions; + +namespace FartingUnicorn.Generated; + +public static partial class Mappers +{ + public static Result MapToFartingUnicorn_Tests_SingleField_EnumType_NonNullableNonOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) + { + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) + { + path = ["$"]; + } + if (jsonElement.ValueKind != JsonValueKind.Object) + { + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); + } + var obj = new FartingUnicorn.Tests.SingleField.EnumType.NonNullableNonOptional_Tests.BlogPost(); + + List errors = new(); + var isStatusPropertyDefined = jsonElement.TryGetProperty("Status", out var jsonStatusProperty); + if (isStatusPropertyDefined) + { + // type = FartingUnicorn.Tests.SingleField.EnumType.NonNullableNonOptional_Tests.BlogPost.BlogPostStatus, isOption = False, isNullable = False + if (jsonStatusProperty.ValueKind == JsonValueKind.Null) + { + errors.Add(new RequiredValueMissingError([.. path, "Status"])); + } + if (mapperOptions.TryGetConverter(typeof(FartingUnicorn.Tests.SingleField.EnumType.NonNullableNonOptional_Tests.BlogPost.BlogPostStatus), out IConverter customConverter)) + { + if (jsonStatusProperty.ValueKind != customConverter.ExpectedJsonValueKind) + { + errors.Add(new ValueHasWrongTypeError(path, customConverter.ExpectedJsonValueKind.ToString(), jsonStatusProperty.ValueKind.ToString())); + } + var result = customConverter.Convert(typeof(FartingUnicorn.Tests.SingleField.EnumType.NonNullableNonOptional_Tests.BlogPost.BlogPostStatus), jsonStatusProperty, mapperOptions, path); + if (result.Success) + { + obj.Status = result.Map(x => (FartingUnicorn.Tests.SingleField.EnumType.NonNullableNonOptional_Tests.BlogPost.BlogPostStatus)x).Value; + } + else + { + errors.AddRange(result.Errors.Select(x => new MappingError(path, x.Message)).ToArray()); + } + } + } + else + { + errors.Add(new RequiredPropertyMissingError([.. path, "Status"])); + } + if(errors.Any()) + { + return Result.Error(errors); + } + if(false)/*check if is option*/ + { + } + else + { + return Result.Ok(obj); + } + throw new NotImplementedException(); + } +} diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NonNullableNonOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NonNullableNonOptional_Tests.BlogPost.g.cs index c58c5bb..65d0303 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NonNullableNonOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NonNullableNonOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_IntType_NonNullableNonOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_IntType_NonNullableNonOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.IntType.NonNullableNonOptional_Tests.BlogPost(); @@ -24,7 +26,7 @@ public static partial class Mappers var isRatingPropertyDefined = jsonElement.TryGetProperty("Rating", out var jsonRatingProperty); if (isRatingPropertyDefined) { - // type = Int32, isOption = False, isNullable = False + // type = System.Int32, isOption = False, isNullable = False if (jsonRatingProperty.ValueKind == JsonValueKind.Null) { errors.Add(new RequiredValueMissingError([.. path, "Rating"])); diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NonNullableOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NonNullableOptional_Tests.BlogPost.g.cs index 1437eeb..0921e9b 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NonNullableOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NonNullableOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_IntType_NonNullableOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_IntType_NonNullableOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.IntType.NonNullableOptional_Tests.BlogPost(); @@ -24,10 +26,10 @@ public static partial class Mappers var isRatingPropertyDefined = jsonElement.TryGetProperty("Rating", out var jsonRatingProperty); if (isRatingPropertyDefined) { - // type = Int32, isOption = True, isNullable = False + // type = System.Int32, isOption = True, isNullable = False if (jsonRatingProperty.ValueKind == JsonValueKind.Null) { - obj.Rating = new None(); + obj.Rating = new None(); } else if (jsonRatingProperty.ValueKind == JsonValueKind.Number) { diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NullableNonOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NullableNonOptional_Tests.BlogPost.g.cs index c736372..f2c37a5 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NullableNonOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NullableNonOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_IntType_NullableNonOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_IntType_NullableNonOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.IntType.NullableNonOptional_Tests.BlogPost(); @@ -24,7 +26,7 @@ public static partial class Mappers var isRatingPropertyDefined = jsonElement.TryGetProperty("Rating", out var jsonRatingProperty); if (isRatingPropertyDefined) { - // type = Int32, isOption = False, isNullable = True + // type = System.Int32, isOption = False, isNullable = True if (jsonRatingProperty.ValueKind == JsonValueKind.Null) { errors.Add(new RequiredValueMissingError([.. path, "Rating"])); diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NullableOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NullableOptional_Tests.BlogPost.g.cs index 43ca522..9c35daf 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NullableOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.IntType.NullableOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_IntType_NullableOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_IntType_NullableOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.IntType.NullableOptional_Tests.BlogPost(); @@ -24,10 +26,10 @@ public static partial class Mappers var isRatingPropertyDefined = jsonElement.TryGetProperty("Rating", out var jsonRatingProperty); if (isRatingPropertyDefined) { - // type = Int32, isOption = True, isNullable = True + // type = System.Int32, isOption = True, isNullable = True if (jsonRatingProperty.ValueKind == JsonValueKind.Null) { - obj.Rating = new None(); + obj.Rating = new None(); } else if (jsonRatingProperty.ValueKind == JsonValueKind.Number) { diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NonNullableNonOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NonNullableNonOptional_Tests.BlogPost.g.cs index 4a52fff..fea5eb8 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NonNullableNonOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NonNullableNonOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_StringType_NonNullableNonOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_StringType_NonNullableNonOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.StringType.NonNullableNonOptional_Tests.BlogPost(); @@ -24,7 +26,7 @@ public static partial class Mappers var isTitlePropertyDefined = jsonElement.TryGetProperty("Title", out var jsonTitleProperty); if (isTitlePropertyDefined) { - // type = String, isOption = False, isNullable = False + // type = System.String, isOption = False, isNullable = False if (jsonTitleProperty.ValueKind == JsonValueKind.Null) { errors.Add(new RequiredValueMissingError([.. path, "Title"])); diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NonNullableOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NonNullableOptional_Tests.BlogPost.g.cs index 8e83552..64cd79c 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NonNullableOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NonNullableOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_StringType_NonNullableOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_StringType_NonNullableOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.StringType.NonNullableOptional_Tests.BlogPost(); @@ -24,10 +26,10 @@ public static partial class Mappers var isTitlePropertyDefined = jsonElement.TryGetProperty("Title", out var jsonTitleProperty); if (isTitlePropertyDefined) { - // type = String, isOption = True, isNullable = False + // type = System.String, isOption = True, isNullable = False if (jsonTitleProperty.ValueKind == JsonValueKind.Null) { - obj.Title = new None(); + obj.Title = new None(); } else if (jsonTitleProperty.ValueKind == JsonValueKind.String) { diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NullableNonOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NullableNonOptional_Tests.BlogPost.g.cs index 98a439a..db35a57 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NullableNonOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NullableNonOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_StringType_NullableNonOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_StringType_NullableNonOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.StringType.NullableNonOptional_Tests.BlogPost(); @@ -24,7 +26,7 @@ public static partial class Mappers var isTitlePropertyDefined = jsonElement.TryGetProperty("Title", out var jsonTitleProperty); if (isTitlePropertyDefined) { - // type = String, isOption = False, isNullable = True + // type = System.String, isOption = False, isNullable = True if (jsonTitleProperty.ValueKind == JsonValueKind.Null) { errors.Add(new RequiredValueMissingError([.. path, "Title"])); diff --git a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NullableOptional_Tests.BlogPost.g.cs b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NullableOptional_Tests.BlogPost.g.cs index 01462ab..ca00f29 100644 --- a/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NullableOptional_Tests.BlogPost.g.cs +++ b/FartingUnicorn.Tests/Generated/MapperGenerator/MapperGenerator.MapperGenerator/Mapper.FartingUnicorn.Tests.SingleField.StringType.NullableOptional_Tests.BlogPost.g.cs @@ -1,22 +1,24 @@ using DotNetThoughts.Results; using System.Text.Json; +using static FartingUnicorn.MapperOptions; namespace FartingUnicorn.Generated; public static partial class Mappers { - public static Result MapToFartingUnicorn_Tests_SingleField_StringType_NullableOptional_Tests_BlogPost(JsonElement jsonElement, string[] path = null) + public static Result MapToFartingUnicorn_Tests_SingleField_StringType_NullableOptional_Tests_BlogPost(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null) { - if(path is null) + if (mapperOptions is null) + { + mapperOptions = new MapperOptions(); + } + if (path is null) { path = ["$"]; } - /*object*/ + if (jsonElement.ValueKind != JsonValueKind.Object) { - if (jsonElement.ValueKind != JsonValueKind.Object) - { - return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); - } + return Result.Error(new ValueHasWrongTypeError(path, "Object", jsonElement.ValueKind.ToString())); } var obj = new FartingUnicorn.Tests.SingleField.StringType.NullableOptional_Tests.BlogPost(); @@ -24,10 +26,10 @@ public static partial class Mappers var isTitlePropertyDefined = jsonElement.TryGetProperty("Title", out var jsonTitleProperty); if (isTitlePropertyDefined) { - // type = String, isOption = True, isNullable = True + // type = System.String, isOption = True, isNullable = True if (jsonTitleProperty.ValueKind == JsonValueKind.Null) { - obj.Title = new None(); + obj.Title = new None(); } else if (jsonTitleProperty.ValueKind == JsonValueKind.String) { diff --git a/FartingUnicorn.Tests/SingleField.cs b/FartingUnicorn.Tests/SingleField.cs index 6890087..1a015c7 100644 --- a/FartingUnicorn.Tests/SingleField.cs +++ b/FartingUnicorn.Tests/SingleField.cs @@ -396,7 +396,7 @@ public class NullableNonOptional_Tests [(Func>)(x => Map(x, null, null))], [(Func>)(x => FartingUnicorn.Generated.Mappers.MapToFartingUnicorn_Tests_SingleField_BoolType_NullableNonOptional_Tests_BlogPost(x, null))] ]; - + [CreateMapper] public class BlogPost { @@ -878,4 +878,303 @@ public void NulledOptionalField(Func> map) } } } + + public class EnumType + { + + public class NonNullableNonOptional_Tests + { + + public static IEnumerable GetMappers + { + get + { + var mapperOptions = new MapperOptions(); + mapperOptions.AddConverter(new EnumAsStringConverter()); + return [ + [(Func>)(x => Map(x, mapperOptions, null))], + [(Func>)(x => Generated.Mappers.MapToFartingUnicorn_Tests_SingleField_EnumType_NonNullableNonOptional_Tests_BlogPost(x, mapperOptions, null))] + ]; + } + } + + [CreateMapper] + public class BlogPost + { + public enum BlogPostStatus { Draft, Published } + + /// + /// Field must exist + /// Value cannot be null + /// + public BlogPostStatus Status { get; set; } + } + + [Theory] + [MemberData(nameof(GetMappers))] + public void ValidSingleField(Func> map) + { + var jsonElement = JsonSerializer.Deserialize(""" + { + "Status": "Published" + } + """); + var blogPost = map(jsonElement); + + Assert.True(blogPost.Success); + blogPost.Value.Status.Should().Be(BlogPost.BlogPostStatus.Published); + } + + //[Theory] + //[MemberData(nameof(GetMappers))] + //public void MissingNonNullableField(Func> map) + //{ + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // } + // """); + // var blogPost = map(jsonElement); + + // Assert.False(blogPost.Success); + // blogPost.Errors.Should().ContainSingle(); + // blogPost.Errors.Single().Should().BeOfType(); + // blogPost.Errors.Single().Message.Should().Be("$.Rating is required"); + //} + + //[Theory] + //[MemberData(nameof(GetMappers))] + //public void NulledNonNullableField(Func> map) + //{ + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // "Rating": null + // } + // """); + // var blogPost = map(jsonElement); + + // Assert.False(blogPost.Success); + // blogPost.Errors.Should().ContainSingle(); + // blogPost.Errors.Single().Should().BeOfType(); + // blogPost.Errors.Single().Message.Should().Be("$.Rating must have a value"); + //} + + //[Theory] + //[MemberData(nameof(GetMappers))] + //public void InvalidFieldType(Func> map) + //{ + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // "Rating": true + // } + // """); + // var blogPost = map(jsonElement); + + // Assert.False(blogPost.Success); + // blogPost.Errors.Should().ContainSingle(); + // blogPost.Errors.Single().Should().BeOfType(); + // blogPost.Errors.Single().Message.Should().Be("Value of $.Rating has the wrong type. Expected Number, got True"); + //} + } + + //public class NullableNonOptional_Tests + //{ + // public static IEnumerable GetMappers => + // [ + // [(Func>)(x => Map(x, null, null))], + // [(Func>)(x => FartingUnicorn.Generated.Mappers.MapToFartingUnicorn_Tests_SingleField_IntType_NullableNonOptional_Tests_BlogPost(x, null))] + // ]; + + // [CreateMapper] + // public class BlogPost + // { + // /// + // /// Field can be missing + // /// Value cannot be null + // /// + // public int? Rating { get; set; } + // } + + // [Theory] + // [MemberData(nameof(GetMappers))] + // public void ValidSingleField(Func> map) + // { + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // "Rating": 5 + // } + // """); + // var blogPost = map(jsonElement); + + // Assert.True(blogPost.Success); + // blogPost.Value.Rating.Should().Be(5); + // } + + // [Theory] + // [MemberData(nameof(GetMappers))] + // public void MissingNullableField(Func> map) + // { + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // } + // """); + // var blogPost = map(jsonElement); + + // Assert.True(blogPost.Success); + // blogPost.Value.Rating.Should().BeNull(); + // } + + // [Theory] + // [MemberData(nameof(GetMappers))] + // public void NulledNullableField(Func> map) + // { + // // Might seem counterintuitive, but remember, we said that + // // clr-null should reflect a missing field. In this case, the field exists, but does not have a value. + // // This would be equivalent to None in an Option type. + // // Therefor, this is not valid json for a nullable field. + // // If the field exists, it must have a value! + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // "Rating": null + // } + // """); + // var blogPost = map(jsonElement); + + // Assert.False(blogPost.Success); + // blogPost.Errors.Should().ContainSingle(); + // blogPost.Errors.Single().Should().BeOfType(); + // blogPost.Errors.Single().Message.Should().Be("$.Rating must have a value"); + // } + //} + + //public class NonNullableOptional_Tests + //{ + // public static IEnumerable GetMappers => + // [ + // [(Func>)(x => Map(x, null, null))], + // [(Func>)(x => FartingUnicorn.Generated.Mappers.MapToFartingUnicorn_Tests_SingleField_IntType_NonNullableOptional_Tests_BlogPost(x, null))] + // ]; + // [CreateMapper] + // public class BlogPost + // { + // /// + // /// Field must exist + // /// Value can be null + // /// + // public Option Rating { get; set; } + // } + + // [Theory] + // [MemberData(nameof(GetMappers))] + // public void ValidSingleField(Func> map) + // { + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // "Rating": 5 + // } + // """); + // var blogPost = map(jsonElement); + + // Assert.True(blogPost.Success); + // blogPost.Value.Rating.Should().BeOfType>(); + // var someIsDraft = (blogPost.Value.Rating as Some)!; + // someIsDraft.Value.Should().Be(5); + // } + + // [Theory] + // [MemberData(nameof(GetMappers))] + // public void MissingNonNullableField(Func> map) + // { + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // } + // """); + // var blogPost = map(jsonElement); + + // Assert.False(blogPost.Success); + // blogPost.Errors.Should().ContainSingle(); + // blogPost.Errors.Single().Should().BeOfType(); + // blogPost.Errors.Single().Message.Should().Be("$.Rating is required"); + // } + + // [Theory] + // [MemberData(nameof(GetMappers))] + // public void NulledOptionalField(Func> map) + // { + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // "Rating": null + // } + // """); + // var blogPost = map(jsonElement); + + // Assert.True(blogPost.Success); + // blogPost.Value.Rating.Should().BeOfType>(); + // } + //} + + //public class NullableOptional_Tests + //{ + // public static IEnumerable GetMappers => + // [ + // [(Func>)(x => Map(x, null, null))], + // [(Func>)(x => FartingUnicorn.Generated.Mappers.MapToFartingUnicorn_Tests_SingleField_IntType_NullableOptional_Tests_BlogPost(x, null))] + // ]; + + // [CreateMapper] + // public class BlogPost + // { + // /// + // /// Field can be missing + // /// Value can be null + // /// + // public Option? Rating { get; set; } + // } + + // [Theory] + // [MemberData(nameof(GetMappers))] + // public void ValidSingleField(Func> map) + // { + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // "Rating": 5 + // } + // """); + // var blogPost = map(jsonElement); + + // blogPost.Should().BeSuccessful(); + // blogPost.Value.Rating.Should().BeOfType>(); + // var someIsDraft = (blogPost.Value.Rating as Some)!; + // someIsDraft.Value.Should().Be(5); + // } + + // [Theory] + // [MemberData(nameof(GetMappers))] + // public void MissingOptionalField(Func> map) + // { + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // } + // """); + // var blogPost = map(jsonElement); + + // blogPost.Should().BeSuccessful(); + // blogPost.Value.Rating.Should().BeNull(); + // } + + // [Theory] + // [MemberData(nameof(GetMappers))] + // public void NulledOptionalField(Func> map) + // { + // var jsonElement = JsonSerializer.Deserialize(""" + // { + // "Rating": null + // } + // """); + // var blogPost = map(jsonElement); + + // blogPost.Should().BeSuccessful(); + // blogPost.Value.Rating.Should().BeOfType>(); + // } + //} + } } diff --git a/FartingUnicorn/Mapper.cs b/FartingUnicorn/Mapper.cs index 9c925d3..247139d 100644 --- a/FartingUnicorn/Mapper.cs +++ b/FartingUnicorn/Mapper.cs @@ -2,36 +2,11 @@ using Namotion.Reflection; -using System.Diagnostics.CodeAnalysis; using System.Text.Json; using static FartingUnicorn.MapperOptions; namespace FartingUnicorn; -public class MapperOptions -{ - public interface IConverter - { - bool CanConvert(Type clrType); - - JsonValueKind ExpectedJsonValueKind { get; } - - Result Convert(Type clrType, JsonElement jsonElement, MapperOptions mapperOptions, string[] path); - } - - public List _converters = []; - - public void AddConverter(IConverter converter) - { - _converters.Add(converter); - } - - public bool TryGetConverter(Type type, [NotNullWhen(true)] out IConverter? converter) - { - converter = _converters.FirstOrDefault(x => x.CanConvert(type)); - return converter != null; - } -} public abstract record FartingUnicornErrorBase(string[] Path, string Message) : ErrorBase(Message); public record MappingError(string[] Path, string Message) : FartingUnicornErrorBase(Path, $"Failed to map {string.Join(".", Path)}: {Message}"); public record RequiredPropertyMissingError(string[] Path) : FartingUnicornErrorBase(Path, $"{string.Join(".", Path)} is required"); diff --git a/FartingUnicorn/MapperOptions.cs b/FartingUnicorn/MapperOptions.cs new file mode 100644 index 0000000..9f64e70 --- /dev/null +++ b/FartingUnicorn/MapperOptions.cs @@ -0,0 +1,31 @@ +using DotNetThoughts.Results; + +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; + +namespace FartingUnicorn; + +public class MapperOptions +{ + public interface IConverter + { + bool CanConvert(Type clrType); + + JsonValueKind ExpectedJsonValueKind { get; } + + Result Convert(Type clrType, JsonElement jsonElement, MapperOptions mapperOptions, string[] path); + } + + public List _converters = []; + + public void AddConverter(IConverter converter) + { + _converters.Add(converter); + } + + public bool TryGetConverter(Type type, [NotNullWhen(true)] out IConverter? converter) + { + converter = _converters.FirstOrDefault(x => x.CanConvert(type)); + return converter != null; + } +} diff --git a/MapperGenerator/CodeAnalysisExtensions.cs b/MapperGenerator/CodeAnalysisExtensions.cs index 5f8c94a..dfb54f1 100644 --- a/MapperGenerator/CodeAnalysisExtensions.cs +++ b/MapperGenerator/CodeAnalysisExtensions.cs @@ -6,6 +6,13 @@ namespace MapperGenerator; public static partial class CodeAnalysisExtensions { + public static string FullTypeName(this ITypeSymbol typeSymbol) => + typeSymbol.ToDisplayString(new SymbolDisplayFormat( + SymbolDisplayGlobalNamespaceStyle.Omitted, + SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, + SymbolDisplayGenericsOptions.IncludeTypeParameters, + miscellaneousOptions: SymbolDisplayMiscellaneousOptions.ExpandNullable + )); public static bool IsNullable(this ITypeSymbol typeSymbol) => typeSymbol.NullableAnnotation == NullableAnnotation.Annotated; diff --git a/MapperGenerator/EquatableArray.cs b/MapperGenerator/EquatableArray.cs new file mode 100644 index 0000000..4306868 --- /dev/null +++ b/MapperGenerator/EquatableArray.cs @@ -0,0 +1,102 @@ +using System.Collections; + +namespace MapperGenerator; + +public readonly struct EquatableArray : IEquatable>, IEnumerable + where T : IEquatable +{ + /// + /// The underlying array. + /// + private readonly T[]? _array; + + /// + /// Initializes a new instance of the struct. + /// + /// The input array to wrap. + public EquatableArray(T[] array) + { + _array = array; + } + + /// + /// Gets the length of the array, or 0 if the array is null + /// + public int Count => _array?.Length ?? 0; + + /// + /// Checks whether two values are the same. + /// + /// The first value. + /// The second value. + /// Whether and are equal. + public static bool operator ==(EquatableArray left, EquatableArray right) + { + return left.Equals(right); + } + + /// + /// Checks whether two values are not the same. + /// + /// The first value. + /// The second value. + /// Whether and are not equal. + public static bool operator !=(EquatableArray left, EquatableArray right) + { + return !left.Equals(right); + } + + /// + public bool Equals(EquatableArray array) + { + return AsSpan().SequenceEqual(array.AsSpan()); + } + + /// + public override bool Equals(object? obj) + { + return obj is EquatableArray array && Equals(this, array); + } + + /// + public override int GetHashCode() + { + if (_array is not T[] array) + { + return 0; + } + + return ((IStructuralEquatable)_array).GetHashCode(EqualityComparer.Default); + + } + + /// + /// Returns a wrapping the current items. + /// + /// A wrapping the current items. + public ReadOnlySpan AsSpan() + { + return _array.AsSpan(); + } + + /// + /// Returns the underlying wrapped array. + /// + /// Returns the underlying array. + public T[]? AsArray() + { + return _array; + } + + /// + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)(_array ?? Array.Empty())).GetEnumerator(); + } + + /// + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)(_array ?? Array.Empty())).GetEnumerator(); + } +} diff --git a/MapperGenerator/MapperGenerator.cs b/MapperGenerator/MapperGenerator.cs index 6057921..483bf9a 100644 --- a/MapperGenerator/MapperGenerator.cs +++ b/MapperGenerator/MapperGenerator.cs @@ -2,7 +2,6 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; -using System.Collections; using System.Collections.Immutable; using System.Text; @@ -29,6 +28,7 @@ public static SourceText GenerateExtensionClass(ClassToGenerateMapperFor classTo var sb = new SourceBuilder(); sb.AppendLine("using DotNetThoughts.Results;"); sb.AppendLine("using System.Text.Json;"); + sb.AppendLine("using static FartingUnicorn.MapperOptions;"); sb.AppendLine(); sb.AppendLine("namespace FartingUnicorn.Generated;"); sb.AppendLine(); @@ -36,24 +36,27 @@ public static SourceText GenerateExtensionClass(ClassToGenerateMapperFor classTo sb.AppendLine($"public static partial class Mappers"); using (var _1 = sb.CodeBlock()) { - sb.AppendLine($"public static Result<{classToGenerateMapperFor.FullName}> MapTo{classToGenerateMapperFor.FullName.Replace(".", "_")}(JsonElement jsonElement, string[] path = null)"); + sb.AppendLine($"public static Result<{classToGenerateMapperFor.FullName}> MapTo{classToGenerateMapperFor.FullName.Replace(".", "_")}(JsonElement jsonElement, MapperOptions mapperOptions = null, string[] path = null)"); using (var _2 = sb.CodeBlock()) { - sb.AppendLine("if(path is null)"); + sb.AppendLine("if (mapperOptions is null)"); using (var _3 = sb.CodeBlock()) { - sb.AppendLine("path = [\"$\"];"); + sb.AppendLine("mapperOptions = new MapperOptions();"); } - sb.AppendLine("/*object*/"); + sb.AppendLine("if (path is null)"); using (var _3 = sb.CodeBlock()) { - sb.AppendLine("if (jsonElement.ValueKind != JsonValueKind.Object)"); - using (var _4 = sb.CodeBlock()) - { - sb.AppendLine($"return Result<{classToGenerateMapperFor.FullName}>.Error(new ValueHasWrongTypeError(path, \"Object\", jsonElement.ValueKind.ToString()));"); - } + sb.AppendLine("path = [\"$\"];"); + } + + sb.AppendLine("if (jsonElement.ValueKind != JsonValueKind.Object)"); + using (var _4 = sb.CodeBlock()) + { + sb.AppendLine($"return Result<{classToGenerateMapperFor.FullName}>.Error(new ValueHasWrongTypeError(path, \"Object\", jsonElement.ValueKind.ToString()));"); } + sb.AppendLine($"var obj = new {classToGenerateMapperFor.FullName}();"); sb.AppendLine(); sb.AppendLine("List errors = new();"); @@ -77,8 +80,7 @@ public static SourceText GenerateExtensionClass(ClassToGenerateMapperFor classTo sb.AppendLine($"errors.Add(new RequiredValueMissingError([.. path, \"{p.Name}\"]));"); } } - - if (p.Type == "String") + if (p.Type == "System.String") { sb.AppendLine($"else if (json{p.Name}Property.ValueKind == JsonValueKind.String)"); using (var _4 = sb.CodeBlock()) @@ -99,7 +101,7 @@ public static SourceText GenerateExtensionClass(ClassToGenerateMapperFor classTo sb.AppendLine($"errors.Add(new ValueHasWrongTypeError([.. path, \"{p.Name}\"], \"String\", json{p.Name}Property.ValueKind.ToString()));"); } } - else if(p.Type == "Boolean") + else if(p.Type == "System.Boolean") { sb.AppendLine($"else if (json{p.Name}Property.ValueKind == JsonValueKind.True || json{p.Name}Property.ValueKind == JsonValueKind.False)"); using (var _4 = sb.CodeBlock()) @@ -120,7 +122,7 @@ public static SourceText GenerateExtensionClass(ClassToGenerateMapperFor classTo sb.AppendLine($"errors.Add(new ValueHasWrongTypeError([.. path, \"{p.Name}\"], \"Boolean\", json{p.Name}Property.ValueKind.ToString()));"); } } - else if (p.Type == "Int32") + else if (p.Type == "System.Int32") { sb.AppendLine($"else if (json{p.Name}Property.ValueKind == JsonValueKind.Number)"); using (var _4 = sb.CodeBlock()) @@ -141,6 +143,29 @@ public static SourceText GenerateExtensionClass(ClassToGenerateMapperFor classTo sb.AppendLine($"errors.Add(new ValueHasWrongTypeError([.. path, \"{p.Name}\"], \"Number\", json{p.Name}Property.ValueKind.ToString()));"); } } + else + { + sb.AppendLine($"if (mapperOptions.TryGetConverter(typeof({p.Type}), out IConverter customConverter))"); + using(var _4 = sb.CodeBlock()) + { + sb.AppendLine($"if (json{p.Name}Property.ValueKind != customConverter.ExpectedJsonValueKind)"); + using(var _5 = sb.CodeBlock()) + { + sb.AppendLine($"errors.Add(new ValueHasWrongTypeError(path, customConverter.ExpectedJsonValueKind.ToString(), json{p.Name}Property.ValueKind.ToString()));"); + } + sb.AppendLine($"var result = customConverter.Convert(typeof({p.Type}), json{p.Name}Property, mapperOptions, path);"); + sb.AppendLine("if (result.Success)"); + using(var _5 = sb.CodeBlock()) + { + sb.AppendLine($"obj.{p.Name} = result.Map(x => ({p.Type})x).Value;"); + } + sb.AppendLine("else"); + using (var _5 = sb.CodeBlock()) + { + sb.AppendLine("errors.AddRange(result.Errors.Select(x => new MappingError(path, x.Message)).ToArray());"); + } + } + } } sb.AppendLine("else"); using (var _3 = sb.CodeBlock()) @@ -259,13 +284,13 @@ static bool IsSyntaxTargetForGeneration(SyntaxNode node) var t = p.Type; var isOptions = t.Name == "Option"; var tName = !isOptions - ? p.Type.Name - : ((INamedTypeSymbol)p.Type).TypeArguments.First().Name; + ? p.Type.FullTypeName() + : ((INamedTypeSymbol)p.Type).TypeArguments.First().FullTypeName(); var isNullable = t.IsNullable(); if (t.IsNullableValueType()) { - tName = ((INamedTypeSymbol)p.Type).TypeArguments.First().Name; + tName = ((INamedTypeSymbol)p.Type).TypeArguments.First().FullTypeName(); } properties.Add(new PropertyToGenerateMapperFor(p.Name, tName, isOptions, isNullable)); } @@ -303,102 +328,3 @@ public ClassToGenerateMapperFor(string fullName, string name, List : IEquatable>, IEnumerable - where T : IEquatable -{ - /// - /// The underlying array. - /// - private readonly T[]? _array; - - /// - /// Initializes a new instance of the struct. - /// - /// The input array to wrap. - public EquatableArray(T[] array) - { - _array = array; - } - - /// - /// Gets the length of the array, or 0 if the array is null - /// - public int Count => _array?.Length ?? 0; - - /// - /// Checks whether two values are the same. - /// - /// The first value. - /// The second value. - /// Whether and are equal. - public static bool operator ==(EquatableArray left, EquatableArray right) - { - return left.Equals(right); - } - - /// - /// Checks whether two values are not the same. - /// - /// The first value. - /// The second value. - /// Whether and are not equal. - public static bool operator !=(EquatableArray left, EquatableArray right) - { - return !left.Equals(right); - } - - /// - public bool Equals(EquatableArray array) - { - return AsSpan().SequenceEqual(array.AsSpan()); - } - - /// - public override bool Equals(object? obj) - { - return obj is EquatableArray array && Equals(this, array); - } - - /// - public override int GetHashCode() - { - if (_array is not T[] array) - { - return 0; - } - - return ((IStructuralEquatable)_array).GetHashCode(EqualityComparer.Default); - - } - - /// - /// Returns a wrapping the current items. - /// - /// A wrapping the current items. - public ReadOnlySpan AsSpan() - { - return _array.AsSpan(); - } - - /// - /// Returns the underlying wrapped array. - /// - /// Returns the underlying array. - public T[]? AsArray() - { - return _array; - } - - /// - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable)(_array ?? Array.Empty())).GetEnumerator(); - } - - /// - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable)(_array ?? Array.Empty())).GetEnumerator(); - } -}