I am trying to take values and move them through a pipeline, where in each stage a different action takes place.
In a simple example which does not use Box<T>
I can make this work:
let mut source: Vec<u32> = vec![4, 3, 2];
let mut stage_a: Option<u32> = Some(1);
let mut stage_b: Option<u32> = None;
let mut stage_c: Option<u32> = None;
while stage_a.is_some() || stage_b.is_some() || stage_c.is_some() {
// Stage c
match stage_b {
None => stage_c = None,
Some(v) => stage_c = Some(v),
}
// Stage b
match stage_a {
None => stage_b = None,
Some(v) => stage_b = Some(v),
}
// Stage a
match source.pop() {
None => stage_a = None,
Some(v) => stage_a = Some(v),
}
}
However in my actual use case I need to use Box<dyn SomeTrait>
since I am using trait objects instead of u32
s. Additionally the trait requires &mut self
, so I have to borrow the boxes mutably:
(Note for the simplicity of my self contained code example I have left out the trait, instead I just borrow mutably to achieve the same error)
let mut source: Vec<u32> = vec![4, 3, 2];
let mut stage_a: Option<Box<u32>> = Some(Box::new(1));
let mut stage_b: Option<Box<u32>> = None;
let mut stage_c: Option<Box<u32>> = None;
while stage_a.is_some() || stage_b.is_some() || stage_c.is_some() {
// Stage c
match &mut stage_b {
None => stage_c = None,
Some(v) => stage_c = Some(*v),
}
// Stage b
match &mut stage_a {
None => stage_b = None,
Some(v) => stage_b = Some(*v),
}
// Stage a
match source.pop() {
None => stage_a = None,
Some(v) => stage_a = Some(Box::new(v)),
}
}
The above example will not compile with the error:
error[E0507]: cannot move out of `*v` which is behind a mutable reference
My question is how do I make this pattern work? I feel as if I am going about this the wrong way. I somehow need to move each boxed trait object through the pipeline. To me the simplest way would be to have an individual variable for each stage. However doing so causes me to fight with the borrow checker.
I have been trying to figure this out for the last 2 weeks without success. I could use some help figuring out the correct way to achieve this pattern.