Files
Natan Rolnik 461c18af6f Add LambdaRuntime initializer with LambdaHandler directly with Codable support (#581)
_Add convenience initializer for `LambdaRuntime` to accept
`LambdaHandler` instances directly_

### Motivation:

When using the Swift AWS Lambda Runtime with custom handler types that
conform to `LambdaHandler`, developers previously had two options to
initialize `LambdaRuntime`:

1. Manually wrap their handler with `LambdaCodableAdapter` and
`LambdaHandlerAdapter`:
   ```swift
   let lambdaHandler = MyHandler()
   let handler = LambdaCodableAdapter(
       encoder: JSONEncoder(),
       decoder: JSONDecoder(),
       handler: LambdaHandlerAdapter(handler: lambdaHandler)
   )
   let runtime = LambdaRuntime(handler: handler)
   ```

2. Use a closure-based initializer that indirectly calls the handler:
   ```swift
   let lambdaHandler = MyHandler()
   let runtime = LambdaRuntime { event, context in
       try await lambdaHandler.handle(event, context: context)
   }
   ```

Both approaches are verbose and don't provide a clean, ergonomic API for
the common case of initializing `LambdaRuntime` with a custom
`LambdaHandler` instance. The closure approach also creates an
unnecessary indirection layer, wrapping the handler in a
`ClosureHandler` before adapting it, or using `LambdaCodableAdapter`.

### Modifications:

Added a new convenience initializer to `LambdaRuntime` in
`Lambda+JSON.swift` that accepts a `LambdaHandler` instance directly:

```swift
public convenience init<Event: Decodable, Output, LHandler: LambdaHandler>(
    decoder: JSONDecoder = JSONDecoder(),
    encoder: JSONEncoder = JSONEncoder(),
    logger: Logger = Logger(label: "LambdaRuntime"),
    lambdaHandler: sending LHandler
)
where
    Handler == LambdaCodableAdapter<
        LambdaHandlerAdapter<Event, Output, LHandler>,
        Event,
        Output,
        LambdaJSONEventDecoder,
        LambdaJSONOutputEncoder<Output>
    >,
    LHandler.Event == Event,
    LHandler.Output == Output
```

This initializer handles the wrapping of the `LambdaHandler` with the
necessary adapters internally, matching the pattern already established
for closure-based handlers.

### Result:

Developers can now initialize `LambdaRuntime` with a `LambdaHandler`
instance using a clean, direct API:

```swift
let lambdaHandler = MyHandler()
let runtime = LambdaRuntime(lambdaHandler: lambdaHandler)
```

This provides:
- **Better ergonomics**: More intuitive and less verbose API
- **Consistency**: Matches the pattern of accepting handlers directly,
similar to how `StreamingLambdaHandler` can be used
- **No extra indirection**: Avoids wrapping the handler in an
unnecessary `ClosureHandler` or `LambdaCodableAdapter`
- **Type safety**: Maintains full type inference for `Event` and
`Output` types from the handler
2025-10-09 19:20:19 +02:00
..