MarshalMapper
Marshals value objects back to plain values. Mappers::marshal() inspects each bindable's object, looks up the
mapper provided by the class's #[Marshal]-attributed static method, and runs it — turning an object into the
scalar/array that gets written to the target.
A value object declares its marshal mapper with a #[Marshal] attribute on a static method returning a Mapper:
class ValueObjectMock implements StringValueObject, \Stringable {
function __construct(private readonly string $value) { /* ... */ }
#[Marshal]
static function marshalMapper(): Mapper {
return Mappers::value(fn (ValueObjectMock $mock) => $mock->toScalar());
}
function toScalar(): string { return $this->value; }
}
MarshalMapper resolves that mapper once per class and caches it. null bindables pass through unchanged.
Note:
marshalis the reverse ofunmarshal—unmarshalbuilds objects from plain input,marshalturns objects back into plain output. Use the two together when a value object crosses the bind boundary in both directions.
Example: marshalling a value object to its scalar
$values = [];
Bind::values(new ValueObjectMock('test@email.ch'), null)->toArray($values)
->map(Mappers::marshal())
->exec($this->createMock(MagicContext::class));
var_dump($values);
Output:
array(2) {
[0]=>
string(13) "test@email.ch"
[1]=>
NULL
}
The first bindable is the ValueObjectMock; marshal() runs its marshalMapper() and writes 'test@email.ch' to
the output array. The second bindable is null, which passes through untouched. If the object's class has no
#[Marshal] method, a BindMismatchException is thrown.