Skip to content
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 @@ -12,4 +12,5 @@ internal class DynamoFieldOptions
public bool? OmitIfEmptyString { get; set; }
public string? ToMethod { get; set; }
public string? FromMethod { get; set; }
public string? Format { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,37 +100,33 @@ GeneratorContext context
"Decimal",
analysis.Nullability
),
{ SpecialType: SpecialType.System_DateTime } =>
$"\"{context.MapperOptions.DateTimeFormat}\"".Map(dateFmt =>
CreateStrategy(
"DateTime",
analysis.Nullability,
fromArg: dateFmt,
toArg: dateFmt
)
),
{ SpecialType: SpecialType.System_DateTime } => CreateStrategy(
"DateTime",
analysis.Nullability,
fromArg: $"\"{analysis.FieldOptions?.Format ?? context.MapperOptions.DateTimeFormat}\"",
toArg: $"\"{analysis.FieldOptions?.Format ?? context.MapperOptions.DateTimeFormat}\""
),
INamedTypeSymbol t
when t.IsAssignableTo(WellKnownType.System_DateTimeOffset, context) =>
$"\"{context.MapperOptions.DateTimeFormat}\"".Map(dateFmt =>
CreateStrategy(
"DateTimeOffset",
analysis.Nullability,
fromArg: dateFmt,
toArg: dateFmt
)
CreateStrategy(
"DateTimeOffset",
analysis.Nullability,
fromArg: $"\"{analysis.FieldOptions?.Format ?? context.MapperOptions.DateTimeFormat}\"",
toArg: $"\"{analysis.FieldOptions?.Format ?? context.MapperOptions.DateTimeFormat}\""
),
INamedTypeSymbol t when t.IsAssignableTo(WellKnownType.System_Guid, context) =>
$"\"{context.MapperOptions.GuidFormat}\"".Map(guidFmt =>
CreateStrategy("Guid", analysis.Nullability, fromArg: guidFmt, toArg: guidFmt)
CreateStrategy(
"Guid",
analysis.Nullability,
fromArg: $"\"{analysis.FieldOptions?.Format ?? context.MapperOptions.GuidFormat}\"",
toArg: $"\"{analysis.FieldOptions?.Format ?? context.MapperOptions.GuidFormat}\""
),
INamedTypeSymbol t when t.IsAssignableTo(WellKnownType.System_TimeSpan, context) =>
$"\"{context.MapperOptions.TimeSpanFormat}\"".Map(timeFmt =>
CreateStrategy(
"TimeSpan",
analysis.Nullability,
fromArg: timeFmt,
toArg: timeFmt
)
CreateStrategy(
"TimeSpan",
analysis.Nullability,
fromArg: $"\"{analysis.FieldOptions?.Format ?? context.MapperOptions.TimeSpanFormat}\"",
toArg: $"\"{analysis.FieldOptions?.Format ?? context.MapperOptions.TimeSpanFormat}\""
),
INamedTypeSymbol { TypeKind: TypeKind.Enum } enumType => CreateEnumStrategy(
enumType,
Expand Down Expand Up @@ -189,7 +185,11 @@ GeneratorContext context
)
{
var enumName = enumType.QualifiedName;
var enumFormat = $"\"{context.MapperOptions.EnumFormat}\"";

// Field-level format override > mapper-level default
var format = analysis.FieldOptions?.Format ?? context.MapperOptions.EnumFormat;
var enumFormat = $"\"{format}\"";

var nullableModifier = analysis.Nullability.IsNullableType ? "Nullable" : "";

// Non-nullable enums need a default value in FromItem
Expand Down
38 changes: 38 additions & 0 deletions src/LayeredCraft.DynamoMapper.Runtime/DynamoFieldAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,42 @@ public DynamoFieldAttribute(string memberName) =>
/// Method must have signature: <c>static T MethodName(AttributeValue value)</c>.
/// </remarks>
public string FromMethod { get; set; } = null!;

/// <summary>Gets or sets the format string for types that support formatting.</summary>
/// <remarks>
/// <para>Supported types and their format strings:</para>
/// <list type="bullet">
/// <item>
/// <term>DateTime / DateTimeOffset</term>
/// <description>Standard or custom format strings (e.g., "O", "yyyy-MM-dd", "MM/dd/yyyy")</description>
/// </item>
/// <item>
/// <term>TimeSpan</term>
/// <description>
/// "c" (constant), "g" (general short), "G" (general long), or custom
/// patterns
/// </description>
/// </item>
/// <item>
/// <term>Guid</term>
/// <description>
/// "N" (32 digits), "D" (hyphens), "B" (braces), "P" (parentheses), "X"
/// (hexadecimal)
/// </description>
/// </item>
/// <item>
/// <term>Enum</term>
/// <description>"G" (general), "F" (flags), "D" (decimal), "X" (hexadecimal)</description>
/// </item>
/// </list>
/// <para>
/// When set, this format overrides the mapper-level format (DateTimeFormat, TimeSpanFormat,
/// GuidFormat, EnumFormat).
/// </para>
/// <para>
/// For types that don't support formatting (string, bool, numeric types), this property is
/// ignored.
/// </para>
/// </remarks>
public string Format { get; set; } = null!;
}
Loading
Loading