-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic dispatch #3
Comments
You can do what you're trying to do as follows use bin_proto::{BitRead, ByteOrder, ProtocolRead, Result, TaggedRead};
use std::collections::HashMap;
use std::fmt::Debug;
trait Variant {}
struct Container(Box<dyn Variant>);
type F = dyn Fn(&mut dyn BitRead, ByteOrder, &mut Ctx) -> Result<Box<dyn Variant>>;
struct Ctx<'a>(HashMap<u8, &'a F>);
impl<'a, Tag> TaggedRead<Tag, Ctx<'a>> for Container
where
Tag: TryInto<u8, Error: Debug>,
{
fn read(
read: &mut dyn BitRead,
byte_order: ByteOrder,
ctx: &mut Ctx<'a>,
tag: Tag,
) -> Result<Self> {
let tag = tag.try_into().unwrap();
let constructor = *ctx.0.get(&tag).unwrap();
let inner = constructor(read, byte_order, ctx)?;
Ok(Self(inner))
}
} You could construct a ctx as follows #[derive(ProtocolRead)]
struct ConcreteVariant;
impl Variant for ConcreteVariant {}
impl ConcreteVariant {
fn new<'a>(
read: &mut dyn BitRead,
byte_order: ByteOrder,
ctx: &mut Ctx<'a>,
) -> Result<Box<dyn Variant>> {
Ok(Box::new(<Self as ProtocolRead<_>>::read(
read, byte_order, ctx,
)?))
}
}
let mut ctx = Ctx(HashMap::from([(42, &ConcreteVariant::new as &F)]));
#[derive(ProtocolRead)]
#[protocol(ctx = Ctx<'a>, ctx_generics('a))]
struct Root {
tag: u8
#[protocol(tag = tag)]
container: Container,
} |
With release 0.6.0 you can now do what I described in my previous comment. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As mentioned in #2 , I'm working on a pretty elaborate binary protocol. It's been on a bit of a backburner for a while but recentlyI've been able to allocate some time for this again. And I've hit a bit of a roadblock with deku: The protocol I'm implementing is quite extensible. It defines a base set of configuration objects, but most applications will want to add their own configuration objects. I basically look at it as some kind of weird rpc system.
To implement my proof of concept, I was using enums to handle most of the known variations in the protocol. But since enums are by definition closed sets, I am now looking at dynamic dispatch. The goal would by to have something like (pseudo code):
I've been trying to figure this out with deku, but my main issue has thus far been that deku's DekuReader trait exposes the underlying reader type, which makes it very hard to have dynamic dispatch working at all.
How I would pass the registry deep into the parsing is still an unknown.
So this got me looking at bin-proto again. And reading about the tagging system got me excited; it might even be a good match for my specific use-case.
The text was updated successfully, but these errors were encountered: