Skip to content

Commit 056e1e2

Browse files
committed
Fix source-gen YAML null strings
Fixes #141
1 parent ec342ea commit 056e1e2

2 files changed

Lines changed: 46 additions & 2 deletions

File tree

src/SharpYaml.SourceGenerator/YamlSerializerContextGenerator.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5518,12 +5518,35 @@ private static void EmitReadKnownType(StringBuilder builder, ITypeSymbol typeSym
55185518
var innerIndent = indent + " ";
55195519
if (IsKnownScalar(typeSymbol))
55205520
{
5521+
var scalarType = typeSymbol;
5522+
var acceptsNull = !typeSymbol.IsValueType;
5523+
if (typeSymbol is INamedTypeSymbol nullableType && nullableType.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
5524+
{
5525+
scalarType = nullableType.TypeArguments[0];
5526+
acceptsNull = true;
5527+
}
5528+
55215529
builder.Append(innerIndent).AppendLine("if (reader.TokenType != global::SharpYaml.Serialization.YamlTokenType.Scalar)");
55225530
builder.Append(innerIndent).AppendLine("{");
55235531
builder.Append(innerIndent).AppendLine(" throw global::SharpYaml.Serialization.YamlThrowHelper.ThrowExpectedScalar(reader);");
55245532
builder.Append(innerIndent).AppendLine("}");
5525-
EmitReadScalarAssignment(builder, typeSymbol, valueVarName, indent: innerIndent);
5526-
builder.Append(innerIndent).AppendLine("reader.Read();");
5533+
if (acceptsNull)
5534+
{
5535+
builder.Append(innerIndent).AppendLine("if (global::SharpYaml.Serialization.YamlScalar.IsNull(reader))");
5536+
builder.Append(innerIndent).AppendLine("{");
5537+
builder.Append(innerIndent).AppendLine(" reader.Read();");
5538+
builder.Append(innerIndent).AppendLine("}");
5539+
builder.Append(innerIndent).AppendLine("else");
5540+
builder.Append(innerIndent).AppendLine("{");
5541+
EmitReadScalarAssignment(builder, scalarType, valueVarName, indent: innerIndent + " ");
5542+
builder.Append(innerIndent).AppendLine(" reader.Read();");
5543+
builder.Append(innerIndent).AppendLine("}");
5544+
}
5545+
else
5546+
{
5547+
EmitReadScalarAssignment(builder, scalarType, valueVarName, indent: innerIndent);
5548+
builder.Append(innerIndent).AppendLine("reader.Read();");
5549+
}
55275550
builder.Append(indent).AppendLine("}");
55285551
return;
55295552
}

src/SharpYaml.Tests/Serialization/YamlSerializerSourceGenerationTests.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,8 @@ internal GeneratedInternalJsonCtorModel(string name, int age)
507507
public int Age { get; }
508508
}
509509

510+
internal sealed record GeneratedFunctionDto(string Name, string? Description, string Abbreviation);
511+
510512
internal sealed class GeneratedPopulateChild
511513
{
512514
public int Existing { get; set; }
@@ -632,6 +634,7 @@ public TestYamlSerializerContext(YamlSerializerOptions options)
632634
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
633635
DictionaryKeyPolicy = JsonKnownNamingPolicy.CamelCase)]
634636
[YamlSerializable(typeof(GeneratedWithDefaultOptions))]
637+
[YamlSerializable(typeof(GeneratedFunctionDto))]
635638
internal partial class TestYamlSerializerContextWithOptions : YamlSerializerContext
636639
{
637640
public TestYamlSerializerContextWithOptions()
@@ -755,6 +758,24 @@ public void GeneratedContext_MergeKey_ExplicitKeyBeforeMergeWins()
755758
Assert.AreEqual(38, model.Age);
756759
}
757760

761+
[TestMethod]
762+
public void GeneratedContext_ParameterizedConstructorStringParameterReadsYamlNullAsNull()
763+
{
764+
var context = TestYamlSerializerContextWithOptions.Default;
765+
var yaml = """
766+
name: My Function
767+
description: null
768+
abbreviation: MF
769+
""";
770+
771+
var model = YamlSerializer.Deserialize(yaml, context.GeneratedFunctionDto);
772+
773+
Assert.IsNotNull(model);
774+
Assert.AreEqual("My Function", model.Name);
775+
Assert.IsNull(model.Description);
776+
Assert.AreEqual("MF", model.Abbreviation);
777+
}
778+
758779
[TestMethod]
759780
public void GeneratedContextProvidesTypedMetadata()
760781
{

0 commit comments

Comments
 (0)