in src/AutoRest.CSharp/Common/Output/Models/Types/HelperTypeProviders/ModelSerializationExtensionsProvider.cs [499:656]
private Method BuildWriteObjectValueMethodGeneric()
{
ValueExpression value;
Utf8JsonWriterExpression writer;
ParameterReference options;
MethodSignature signature = GetWriteObjectValueMethodSignature(_t, out value, out writer, out options);
List<SwitchCase> cases = new List<SwitchCase>
{
new(Null, new MethodBodyStatement[]
{
writer.WriteNullValue(),
Break
})
};
if (Configuration.UseModelReaderWriter)
{
cases.Add(
BuildWriteObjectValueSwitchCase(new CSharpType(typeof(IJsonModel<>), _t), "jsonModel", jsonModel => new MethodBodyStatement[]
{
new InvokeInstanceMethodStatement(jsonModel, nameof(IJsonModel<object>.Write), writer, NullCoalescing(options, ModelReaderWriterOptionsExpression.Wire)),
Break
}));
}
if (Configuration.IsBranded)
{
cases.Add(
BuildWriteObjectValueSwitchCase(typeof(IUtf8JsonSerializable), "serializable", serializable => new MethodBodyStatement[]
{
new InvokeInstanceMethodStatement(serializable, nameof(IUtf8JsonSerializable.Write), writer),
Break
}));
}
cases.AddRange(new[]
{
// byte[] case
BuildWriteObjectValueSwitchCase(typeof(byte[]), "bytes", bytes => new MethodBodyStatement[]
{
writer.WriteBase64StringValue(bytes),
Break
}),
// BinaryData case
BuildWriteObjectValueSwitchCase(typeof(BinaryData), "bytes", bytes => new MethodBodyStatement[]
{
writer.WriteBase64StringValue(bytes),
Break
}),
// JsonElement case
BuildWriteObjectValueSwitchCase(typeof(JsonElement), "json", json => new MethodBodyStatement[]
{
new JsonElementExpression(json).WriteTo(writer),
Break
}),
// int case
BuildWriteObjectValueSwitchCase(typeof(int), "i", i => new MethodBodyStatement[]
{
writer.WriteNumberValue(i),
Break
}),
// decimal case
BuildWriteObjectValueSwitchCase(typeof(decimal), "d", dec => new MethodBodyStatement[]
{
writer.WriteNumberValue(dec),
Break
}),
// double case
BuildWriteObjectValueSwitchCase(typeof(double), "d", d => new MethodBodyStatement[]
{
new IfElseStatement(
DoubleExpression.IsNan(d),
writer.WriteStringValue(Literal("NaN")),
writer.WriteNumberValue(d)),
Break
}),
// float case
BuildWriteObjectValueSwitchCase(typeof(float), "f", f => new MethodBodyStatement[]
{
writer.WriteNumberValue(f),
Break
}),
// long case
BuildWriteObjectValueSwitchCase(typeof(long), "l", l => new MethodBodyStatement[]
{
writer.WriteNumberValue(l),
Break
}),
// string case
BuildWriteObjectValueSwitchCase(typeof(string), "s", s => new MethodBodyStatement[]
{
writer.WriteStringValue(s),
Break
}),
// bool case
BuildWriteObjectValueSwitchCase(typeof(bool), "b", b => new MethodBodyStatement[]
{
writer.WriteBooleanValue(b),
Break
}),
// Guid case
BuildWriteObjectValueSwitchCase(typeof(Guid), "g", g => new MethodBodyStatement[]
{
writer.WriteStringValue(g),
Break
}),
// DateTimeOffset case
BuildWriteObjectValueSwitchCase(typeof(DateTimeOffset), "dateTimeOffset", dateTimeOffset => new MethodBodyStatement[]
{
writer.WriteStringValue(dateTimeOffset, "O"),
Break
}),
// DateTime case
BuildWriteObjectValueSwitchCase(typeof(DateTime), "dateTime", dateTime => new MethodBodyStatement[]
{
writer.WriteStringValue(dateTime, "O"),
Break
}),
// IEnumerable<KeyValuePair<>> case
BuildWriteObjectValueSwitchCase(typeof(IEnumerable<KeyValuePair<string, object>>), "enumerable", enumerable => new MethodBodyStatement[]
{
writer.WriteStartObject(),
new ForeachStatement("pair", new EnumerableExpression(typeof(KeyValuePair<string, object>), enumerable), out var pair)
{
writer.WritePropertyName(pair.Property(nameof(KeyValuePair<string, object>.Key))),
writer.WriteObjectValue(new TypedValueExpression(typeof(object), pair.Property(nameof(KeyValuePair<string, object>.Value))), options)
},
writer.WriteEndObject(),
Break
}),
// IEnumerable<object> case
BuildWriteObjectValueSwitchCase(typeof(IEnumerable<object>), "objectEnumerable", objectEnumerable => new MethodBodyStatement[]
{
writer.WriteStartArray(),
new ForeachStatement("item", new EnumerableExpression(typeof(object), objectEnumerable), out var item)
{
writer.WriteObjectValue(new TypedValueExpression(typeof(object), item), options)
},
writer.WriteEndArray(),
Break
}),
// TimeSpan case
BuildWriteObjectValueSwitchCase(typeof(TimeSpan), "timeSpan", timeSpan => new MethodBodyStatement[]
{
writer.WriteStringValue(timeSpan, "P"),
Break
}),
// default
SwitchCase.Default(Throw(New.NotSupportedException(new FormattableStringExpression("Not supported type {0}", value.InvokeGetType()))))
});
return new Method(signature, new SwitchStatement(value, cases));
static SwitchCase BuildWriteObjectValueSwitchCase(CSharpType type, string varName, Func<VariableReference, MethodBodyStatement> bodyFunc)
{
var declaration = new DeclarationExpression(type, varName, out var variable);
var body = bodyFunc(variable);
return new(declaration, body);
}
}