SteveDunn / Vogen

A semi-opinionated library which is a source generator and a code analyser. It Source generates Value Objects
Apache License 2.0
887 stars 46 forks source link

CastOperator.Implicit skip the NormalizeInput #639

Closed bnaya-payoneer closed 4 months ago

bnaya-payoneer commented 4 months ago

Describe the bug

When casting a primitive to the domain type, it skip the NormalizeInput stage

Steps to reproduce

[ValueObject<string>(Conversions.SystemTextJson | Conversions.TypeConverter, // Support for System.Text.Json and TypeConverter for a smooth serialization and deserialization
            toPrimitiveCasting: CastOperator.Implicit, // Implicit casting from Email to string
            fromPrimitiveCasting: CastOperator.Implicit)] // Implicit casting from string to Email
public partial struct PhoneInternationalPrefix
{
    private static string NormalizeInput(string input) => input switch
        {
            null => string.Empty,
            [var c] when IsNumber(c) => $"+{input}",
            [var c] => input, // not valid, will be caught by the regex validation
            [var start,.., var end] when IsWhiteSpace(start) || IsWhiteSpace(end) => NormalizeInput(input.Trim()),
            [var c,..] when c != '+' => $"+{input}",
            _ => input            
        };
}
    [TestMethod]
    public void PhoneInternationalPrefix_FromString_Serialization_ShouldSucceed()
    {
        PhoneInternationalPrefix prefix = "93";
        string json = JsonSerializer.Serialize(prefix);
        PhoneInternationalPrefix clonedPrefix = JsonSerializer.Deserialize<PhoneInternationalPrefix>(json);

        Assert.AreEqual(prefix, clonedPrefix, "serialization problem");
    }

Expected behaviour

Cast should goes through From(value)

I Think that the following code on this location

if (item.Config.FromPrimitiveCasting == CastOperator.Implicit)
        {
            sb.AppendLine(
                $$"""
                          public static implicit operator {{className}}({{itemUnderlyingType}} value) {
                            return new {{className}}(value);
                  }
                  """);
        }

Should be altered to:

if (item.Config.FromPrimitiveCasting == CastOperator.Implicit)
        {
            sb.AppendLine(
                $$"""
                          public static implicit operator {{className}}({{itemUnderlyingType}} value) {
                            return From(value);
                  }
                  """);
        }
SteveDunn commented 4 months ago

@bnaya-payoneer - this is now released - thanks again for reporting.