Consider the following code (simplified but compiled):
use std::sync::Arc; pub trait ActorRef<Message> { } pub trait Actor<Message> { } pub trait ActorSpawner {
Is it possible to implement ActorSpawner::spawn or achieve something similar with a different signature?
Idea
The code in the question is simplified to reduce it to the main parts that I could not solve.
In general, Actor should have a mutable state that changes with processing messages (in this example, there is no process method). You can create an Actor and can communicate with it using ActorRef (there is no submit method in this example).
I want to allow different ways of "spawning" Actor . For instance. message processing can occur in one thread for each actor. Or, processing may be performed in a thread pool that is shared by other participants.
Other code may depend on the creation of other members. The underlying mechanism used should be abstracted. Since the trait is ActorSpawner .
My attempts to solve it
Suppose we have some dummy implementations for Actor and ActorRef :
struct NoopActor; impl<Message> Actor<Message> for NoopActor {} struct DeadRef; impl<Message> ActorRef<Message> for DeadRef {}
It should now be possible to implement this feature using these dummy implementations.
This is my first attempt:
struct DeadActorSpawner; impl ActorSpawner for DeadActorSpawner { fn spawn<Message,A,R>(actor: A) -> Arc<R> where R: ActorRef<Message>, A: Actor<Message> { Arc::new(DeadRef) } }
leads to this error:
error[E0308]: mismatched types --> src/main.rs:29:18 | 29 | Arc::new(DeadRef) | ^^^^^^^ expected type parameter, found struct `DeadRef` | = note: expected type `R` found type `DeadRef`
Or other:
struct DeadActorSpawner; impl ActorSpawner for DeadActorSpawner { fn spawn<Message,A,R>(actor: A) -> Arc<DeadRef> { Arc::new(DeadRef) } }
leads to this error:
error[E0053]: method `spawn` has an incompatible type for trait --> src/main.rs:25:42 | 12 | fn spawn<Message, A, R>(actor: A) -> Arc<R> | ------ type in trait ... 25 | fn spawn<Message, A, R>(actor: A) -> Arc<DeadRef> { | ^^^^^^^^^^^^ expected type parameter, found struct `DeadRef` | = note: expected type `fn(A) -> std::sync::Arc<R>` found type `fn(A) -> std::sync::Arc<DeadRef>`
I tried many other things to no avail, including using related types for Message in Actor and ActorRef .