Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ToJson for DynamoDBEvent #1685

Merged
merged 2 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<TargetFrameworks>netcoreapp3.1;net8.0</TargetFrameworks>
<Description>Amazon Lambda .NET Core support - DynamoDBEvents package.</Description>
<AssemblyTitle>Amazon.Lambda.DynamoDBEvents</AssemblyTitle>
<VersionPrefix>3.0.0</VersionPrefix>
<VersionPrefix>3.1.0</VersionPrefix>
<AssemblyName>Amazon.Lambda.DynamoDBEvents</AssemblyName>
<PackageId>Amazon.Lambda.DynamoDBEvents</PackageId>
<PackageTags>AWS;Amazon;Lambda</PackageTags>
Expand Down
157 changes: 157 additions & 0 deletions Libraries/src/Amazon.Lambda.DynamoDBEvents/ExtensionMethods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.Json;
using static Amazon.Lambda.DynamoDBEvents.DynamoDBEvent;

namespace Amazon.Lambda.DynamoDBEvents
{
/// <summary>
/// Extension methods for working with <see cref="DynamoDBEvent"/>
/// </summary>
public static class ExtensionMethods
{
/// <summary>
/// Converts a dictionary representing a DynamoDB item to a JSON string.
/// This may be useful when casting a DynamoDB Lambda event to the AWS SDK's
/// higher-level document and object persistence classes.
/// </summary>
/// <param name="item">Dictionary representing a DynamoDB item</param>
/// <returns>Unformatted JSON string representing the DynamoDB item</returns>
public static string ToJson(this Dictionary<string, AttributeValue> item)
{
return ToJson(item, false);
}

/// <summary>
/// Converts a dictionary representing a DynamoDB item to a JSON string.
/// This may be useful when casting a DynamoDB Lambda event to the AWS SDK's
/// higher-level document and object persistence classes.
/// </summary>
/// <param name="item">Dictionary representing a DynamoDB item</param>
/// <returns>Formatted JSON string representing the DynamoDB item</returns>
public static string ToJsonPretty(this Dictionary<string, AttributeValue> item)
{
return ToJson(item, true);
}

/// <summary>
/// Internal entry point for converting a dictionary representing a DynamoDB item to a JSON string.
/// </summary>
/// <param name="item">Dictionary representing a DynamoDB item</param>
/// <param name="prettyPrint">Whether the resulting JSON should be formatted</param>
/// <returns>JSON string representing the DynamoDB item</returns>
private static string ToJson(Dictionary<string, AttributeValue> item, bool prettyPrint)
{
if (item == null || item.Count == 0)
{
return "{}";
}

using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = prettyPrint});

WriteJson(writer, item);

writer.Flush();
return Encoding.UTF8.GetString(stream.ToArray());
}

/// <summary>
/// Writes a single DynamoDB attribute as a json. May be called recursively for maps.
/// </summary>
/// <param name="writer">JSON writer</param>
/// <param name="item">Dictionary representing a DynamoDB item, or a map within an item</param>
private static void WriteJson(Utf8JsonWriter writer, Dictionary<string, AttributeValue> item)
{
writer.WriteStartObject();

foreach (var attribute in item)
{
writer.WritePropertyName(attribute.Key);
WriteJsonValue(writer, attribute.Value);
}

writer.WriteEndObject();
}

/// <summary>
/// Writes a single DynamoDB attribute value as a json value
/// </summary>
/// <param name="writer">JSON writer</param>
/// <param name="attribute">DynamoDB attribute</param>
private static void WriteJsonValue(Utf8JsonWriter writer, AttributeValue attribute)
{
if (attribute.S != null)
{
writer.WriteStringValue(attribute.S);
}
else if (attribute.N != null)
{
#if NETCOREAPP3_1 // WriteRawValue was added in .NET 6, but we need to write out Number values without quotes
using var document = JsonDocument.Parse(attribute.N);
document.WriteTo(writer);
#else
writer.WriteRawValue(attribute.N);
#endif
}
else if (attribute.B != null)
{
writer.WriteBase64StringValue(attribute.B.ToArray());
}
else if (attribute.BOOL != null)
{
writer.WriteBooleanValue(attribute.BOOL.Value);
}
else if (attribute.NULL != null)
{
writer.WriteNullValue();
}
else if (attribute.M != null)
{
WriteJson(writer, attribute.M);
}
else if (attribute.L != null)
{
writer.WriteStartArray();
foreach (var item in attribute.L)
{
WriteJsonValue(writer, item);
}
writer.WriteEndArray();
}
else if (attribute.SS != null)
{
writer.WriteStartArray();
foreach (var item in attribute.SS)
{
writer.WriteStringValue(item);
}
writer.WriteEndArray();
}
else if (attribute.NS != null)
{
writer.WriteStartArray();
foreach (var item in attribute.NS)
{
#if NETCOREAPP3_1 // WriteRawValue was added in .NET 6, but we need to write out Number values without quotes
dscpinheiro marked this conversation as resolved.
Show resolved Hide resolved
using var document = JsonDocument.Parse(item);
document.WriteTo(writer);
#else
writer.WriteRawValue(item);
#endif
}
writer.WriteEndArray();
}
else if (attribute.BS != null)
{
writer.WriteStartArray();
foreach (var item in attribute.BS)
{
writer.WriteBase64StringValue(item.ToArray());
}
writer.WriteEndArray();
}
}
}
}
4 changes: 3 additions & 1 deletion Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<PackageId>EventsTests31</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<RootNamespace>EventsTests.NET6</RootNamespace>
<LangVersion>latest</LangVersion>
</PropertyGroup>


Expand Down Expand Up @@ -54,13 +55,14 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.301.14" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="AWSSDK.Core" Version="3.7.10.9" />
<PackageReference Include="AWSSDK.Core" Version="3.7.302.13" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<RuntimeIdentifiers>win7-x64;win7-x86</RuntimeIdentifiers>
<RootNamespace>EventsTests31</RootNamespace>
<LangVersion>latest</LangVersion>
</PropertyGroup>


Expand Down Expand Up @@ -54,10 +55,11 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.301.14" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="AWSSDK.Core" Version="3.7.10.9" />
<PackageReference Include="AWSSDK.Core" Version="3.7.302.13" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading
Loading