Hello,
As a PHP developer, I came across Rust and really love it for all it's features. In my spare time I'd like to work on some personal projects, just to learn Rust better. However, I keep running into the same patterns I use with PHP, which are impossible to implement in Rust (by definition).
I need someone who can tell me how to break those patterns so that I can implement that in a memory-safe way, as Rust intends.
The pattern that I'd like to break can be described the best by using the Symfony (PHP framework) "event-dispatcher" example. And please, I'm not looking for libraries that can do event dispatching or replace my code with another library, I want to break the pattern (which is stuck in my brain) that is used in this particular event-dispatcher:
The scenario:
- You can add event "listeners" by registering callbacks for a specific event name
- You can dispatch a specific event object using the generic event-dispatcher
- The registered callbacks will receive the specific event object
The problem:
- A specific object is dispatched and received in a callback through a generic event-dispatcher
In PHP, this could be something like this:
class MySpecificEvent {}
class SomeOtherSpecificEvent {}
class EventDispatcher {
private $listeners = [];
public function addListener(string $name, callable $callback): void {
$this->listeners[$name][] = $callback;
}
public function dispatch(string $name, object $event): void {
foreach ($this->listeners[$name] as $callback) {
$callback($event);
}
}
}
And the usage:
$eventDispatcher = new EventDispatcher();
$eventDispatcher->addListener("my-specific-event", function (MySpecificEvent $event) {});
$eventDispatcher->addListener("some-other-specific-event", function (SomeOtherSpecificEvent $event) {});
$event = new MySpecificEvent();
$eventDispatcher->dispatch("my-specific-event", $event)
$event = new SomeOtherSpecificEvent();
$eventDispatcher->dispatch("some-other-specific-event", $event)
This means that:
- The signature of
addListener
allows an callback with an arbitrary object as argument to be passed - The signature of
dispatch
allows an arbitrary object to be passed as 2nd argument - The callback would receive the arbitrary object, which would succeed or throw an exception depending on whether the object is of the correct type
Since Rust is memory-safe, it is not possible to just pass arbitrary objects as arguments, they have to be typed and the functions must have a fixed signature.
This "simple" example from above shows a patterns that is stuck in my brain... it might be poisoned by all these years of PHP.
How can such logic be transformed to memory/type-safe Rust? I want to be able to make the mapping in my head, so that I can translate similar scenarios from PHP to Rust more easily.
Any help would be greatly appreciated!
Thanks,
Raymond