I’ve distilled my code to the following small example that demonstrates the error that I’m getting:
I apologize that the example isn’t tiny, but I had such an example and the responses that I got on irc suggest that too much context was lost.
Basically, I’ve written a parser for a packet-based stream. Some of the packets are containers (e.g., an encryption container and a compression container). These containers can contain any other valid packet. This can result in deep nesting, but in practice the amount of nesting is limited. The containers are implemented as filters. When parsing a packet, we effectively have a pipeline.
I’ve tried to design an API that allow progressively parsing the stream. The idea is that the user creates a MessageParser for some data source and calls pp = mp.next() to get the next PacketParser and mp.recurse(pp) to enter a container. Entering a container means creating a ContainerParser and pushing it on the stack, which is stored in the MessageParser (thus, MessageParser owns all of the containers). The data structure looks like:
MessageParser | |-- owns --> ContainerParser (top-level) ------ owns ---> file | ^ mut ref `- owns --> ContainerParser (decompress) -- owns --> decompressor ^ mut ref PacketParser ------------------------- owns -------------> limitor
Note: I can’t change the decompressor to, say, own
file, because when the decompressor’s ContainerParser is popped from the stack, the top-level ContainerParser needs to read the next packet from
Is Rust’s lifetime system not able to handle what I want to do? If it can, I’d appreciate any tips about how to accomplish that. And, more immediately, I’d appreciate any insight into the error that I’m currently getting.