#if NET6_0_OR_GREATER
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using Amazon.Lambda.Core;
using Amazon.Lambda.Serialization.SystemTextJson.Converters;
namespace Amazon.Lambda.Serialization.SystemTextJson
{
///
/// ILambdaSerializer implementation that supports the source generator support of System.Text.Json. To use this serializer define
/// a partial JsonSerializerContext class with attributes for the types to be serialized.
///
/// [JsonSerializable(typeof(APIGatewayHttpApiV2ProxyRequest))]
/// [JsonSerializable(typeof(APIGatewayHttpApiV2ProxyResponse))]
/// public partial class APIGatewaySerializerContext : JsonSerializerContext
/// {
/// }
///
/// Register the serializer with the LambdaSerializer attribute specifying the defined JsonSerializerContext
///
/// [assembly: LambdaSerializer(typeof(SourceGeneratorLambdaJsonSerializer&ly;APIGatewayExampleImage.MyJsonContext>))]
///
/// When the class is compiled it will generate all of the JSON serialization code to convert between JSON and the list types. This
/// will avoid any reflection based serialization.
///
///
public class SourceGeneratorLambdaJsonSerializer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TSGContext> : AbstractLambdaJsonSerializer, ILambdaSerializer where TSGContext : JsonSerializerContext
{
TSGContext _jsonSerializerContext;
///
/// The options used to serialize JSON object.
///
protected JsonSerializerOptions SerializerOptions { get; }
///
/// Constructs instance of serializer.
///
public SourceGeneratorLambdaJsonSerializer()
: this(null, null)
{
}
///
/// Constructs instance of serializer with the option to customize the JsonSerializerOptions after the
/// Amazon.Lambda.Serialization.SystemTextJson's default settings have been applied.
///
///
public SourceGeneratorLambdaJsonSerializer(Action customizer)
: this(customizer, null)
{
}
///
/// Constructs instance of serializer with the option to customize the JsonWriterOptions after the
/// Amazon.Lambda.Serialization.SystemTextJson's default settings have been applied.
///
///
public SourceGeneratorLambdaJsonSerializer(Action jsonWriterCustomizer)
: this(null, jsonWriterCustomizer)
{
}
///
/// Constructs instance of serializer with the option to customize the JsonWriterOptions after the
/// Amazon.Lambda.Serialization.SystemTextJson's default settings have been applied.
///
///
///
public SourceGeneratorLambdaJsonSerializer(Action customizer, Action jsonWriterCustomizer)
: base(jsonWriterCustomizer)
{
SerializerOptions = CreateDefaultJsonSerializationOptions();
customizer?.Invoke(this.SerializerOptions);
var constructor = typeof(TSGContext).GetConstructor(new Type[] { typeof(JsonSerializerOptions) });
if(constructor == null)
{
throw new ApplicationException($"The serializer {typeof(TSGContext).FullName} is missing a constructor that takes in JsonSerializerOptions object");
}
_jsonSerializerContext = constructor.Invoke(new object[] { this.SerializerOptions }) as TSGContext;
}
///
protected override void InternalSerialize(Utf8JsonWriter writer, T response)
{
var jsonTypeInfo = _jsonSerializerContext.GetTypeInfo(typeof(T)) as JsonTypeInfo;
if (jsonTypeInfo == null)
{
throw new JsonSerializerException($"No JsonTypeInfo registered in {_jsonSerializerContext.GetType().FullName} for type {typeof(T).FullName}.");
}
JsonSerializer.Serialize(writer, response, jsonTypeInfo);
}
///
protected override T InternalDeserialize(byte[] utf8Json)
{
var jsonTypeInfo = _jsonSerializerContext.GetTypeInfo(typeof(T)) as JsonTypeInfo;
if (jsonTypeInfo == null)
{
throw new JsonSerializerException($"No JsonTypeInfo registered in {_jsonSerializerContext.GetType().FullName} for type {typeof(T).FullName}.");
}
return JsonSerializer.Deserialize(utf8Json, jsonTypeInfo);
}
}
}
#endif