Skip to content

Add Converter Type Support (IDynamoConverter) #22

@j-d-ha

Description

@j-d-ha

Priority: P2 - Important
Tier: 3 - Advanced Features
Effort: Large (10-16 hours)

Already In Codebase

  • No IDynamoConverter<T> exists in src/LayeredCraft.DynamoMapper.Runtime/.
  • DynamoFieldAttribute does not expose a converter-type property today.
  • Generator has no converter parsing/validation logic.
  • Docs reference IDynamoConverter<T> heavily (e.g., docs/usage/converters.md).

Goal

Support declaring a reusable converter type for a mapped member via class-level [DynamoField].

Example desired usage:

[DynamoMapper]
[DynamoField(nameof(MyEntity.Status), Converter = typeof(OrderStatusConverter))]
public static partial class MyEntityMapper { }

Runtime API (part of this story)

  1. Add IDynamoConverter<T>:
public interface IDynamoConverter<T>
{
    AttributeValue ToAttributeValue(T value);
    T FromAttributeValue(AttributeValue value);
}
  1. Extend DynamoFieldAttribute with:
  • Type? Converter

Generator behavior

  • Validate converter type implements IDynamoConverter<TProperty>.
  • Emit code that uses the converter:
    • Prefer a cached static readonly converter instance per mapper to avoid allocations.
    • Call converter.ToAttributeValue(value) / converter.FromAttributeValue(attributeValue).

Conflicts

  • Converter cannot be used together with ToMethod / FromMethod (emit diagnostic).

Diagnostics

  • Converter type does not implement IDynamoConverter<T>.
  • Converter generic type mismatch with property type.
  • Conflicting converter config.

Tests (must be part of this story)

Add verify tests covering:

  • Happy path: converter type used in generated code.
  • Failure: wrong interface or mismatch emits diagnostic.
  • Failure: converter + ToMethod/FromMethod emits diagnostic.

Acceptance criteria

  • Converter types work for custom member types.
  • Diagnostics are clear and point to the attribute usage.
  • Snapshot tests cover happy path and key failures.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions