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
17 changes: 15 additions & 2 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: PHP Composer

on:
push:
branches: [ "main" ]
branches: [ "main", "develop" ]
pull_request:
branches: [ "main" ]
branches: [ "main", "develop" ]

permissions:
contents: read
Expand All @@ -14,9 +14,22 @@ jobs:

runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
php-version: ['8.3', '8.4', '8.5']

name: PHP ${{ matrix.php-version }} Test

steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
coverage: none

- name: Validate composer.json and composer.lock
run: composer validate --strict

Expand Down
41 changes: 39 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,47 @@ Notes and tips:
- `MapProperty` supports nested keys via dot-notation and works with arrays and
objects; if a segment is missing the default `null` (or provided default) will be returned.
- `MapGetter` requires a callable method on the source — if the method does not
exist a PHP exception will occur, so prefer checks or defensive code on the source
or use a resolver to choose a safer mapping strategy.
exist a `MapGetterResolutionException` will be thrown.
- Use `MapGetter` for computed values and `MapProperty` for direct data lookups.

### Error Handling

Remap exposes a dedicated exception hierarchy under `Luimedi\Remap\Exception`.
All library-specific failures extend `RemapException`, making it simple to catch
all Remap errors in one place.

Main exceptions include:

- `BindingNotFoundException`: no mapping binding exists for the source type.
- `BindingResolutionException`: a binding resolver returned an invalid target type.
- `InvalidTargetTypeException`: the resolved target type could not be instantiated.
- `MapGetterResolutionException`: `MapGetter` could not resolve a source method.
- `MissingMappedValueException`: a caster was applied to a parameter with no mapped value.

Example:

```php
use Luimedi\Remap\Exception\RemapException;

try {
$result = $mapper->map($source);
} catch (RemapException $exception) {
// Centralized handling for all Remap-specific failures.
$mappingTrace = $exception->getMappingTrace();
$previous = $exception->getPrevious(); // Original low-level error, if any.
}
```

`getMappingTrace()` returns an ordered list of mapping steps, for example:

```php
[
['phase' => 'execute', 'targetType' => 'App\\Output', 'sourceType' => 'App\\Input'],
['phase' => 'attribute.transform', 'targetType' => 'App\\Output', 'attribute' => 'Luimedi\\Remap\\Attribute\\ConstructorMapper'],
['phase' => 'constructor.parameter.cast', 'parameter' => 'status', 'caster' => 'Luimedi\\Remap\\Attribute\\Cast\\CastDefault'],
]
```

### Casters

Casters implement `CastInterface` and are responsible for transforming mapped
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
}
],
"require": {
"php": ">=8.0"
"php": ">=8.3"
},
"require-dev": {
"phpunit/phpunit": "^12"
Expand Down
Loading