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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions