rust - Aliasing trait inheritance with generics -
i starting play rust new library. i'm trying wrap head around possible ways implement following.
what follows more of desired expression not real syntax. of ways i've tried express either don't compile, or don't compile when go implement 1 of alias traits.
struct concretetype; struct commontype; trait handler<rin, rout = rin>{ fn handle_event(&self, msg: &rin); } // alias handler 1 of types defined common case trait handlertomessage<m> : handler <concretetype, m>{ fn handle_event(&self, msg: &concretetype) { // default implementation of parent trait // example simplified, forget how rout/m used self.decode(msg) } // method implement fn decode(&self, msg: &concretetype) -> m; } // alias common case rin/rout concretetype, commontype trait handlertocommontype : handlertomessage <concretetype, commontype>{ fn decode(&self, msg: &concretetype) -> commontype { ... }; }
alternative using associated types
trait handler{ type rin; type rout; // not yet able rout = rin associated types fn handle_event(&self, msg: &self::rin) -> self::rout; } trait handlertomessage : handler <rin=concretetype>{ fn handle_event(&self, msg: &self::rin) { // common functionality self.decode(msg) } // method implement fn decode(&self, msg: &self::rin) -> self::rout; } trait handlertocommontype : handlertomessage <rout=commontype>{ fn decode(&self, msg: &concretetype) -> commontype { ... } }
in c++ want accomplish
// real world example i've seen in wild of structure template <class rout> class context { public: void dispatch(rout* msg); }; template <class rin, rout = rin> class readhandler { public: void read (context* ctx, rin* msg) = 0; private: context<rout> ctx_; }; // common convert byte buffer message type template <class m> class bytestomessagedecoder : readhandler<iobuffer, m> { public: // template method pattern void read (context* ctx, iobuffer* msg) { m msgout; bool success; success = this->decode(msg, &msgout); if (success) { ctx->dispatch(msgout); } } bool decode(iobuffer* msg, m* msgout) = 0; } // convert 1 byte buffer common typedef bytestomessagedecoder<iobuffer> bytestobytesdecoder; // concrete implementations // fixed number of bytes incoming class fixedlengthframedecoder : bytestobytesdecoder { bool decode(iobuffer* msg, iobuffer* msgout) { ... } } // fields prefixed length. wait many bytes , dispatch class lengthbasedfielddecoder: bytestobytesdecoder { bool decode(iobuffer* msg, iobuffer* msgout) { ... } } class stringdecoder : bytestomessagedecoder<std::string> { // decode byte buffer string bool decode(iobuffer* msg, std::string* msgout) { ... } }
basically top level trait handler
generic maybe not meant implemented advanced library users. handlertomessage
trait meant common conversion take concretetype
, convert other type. library may implement several of these. handlertocommontype
common case numerous library types want start from.
the details on how rout
used in handler
trait not of importance. tried simplify example , left off arguments make i'm trying convey more concise. of searching on either has me thinking isn't possible convey or misusing it. don't quite understand if falls under new specialization implementation, doesn't feel understanding though.
i realize rust not c++ , maybe i'm trying either not supported or has different syntax. appreciated either in correct syntax or more idiomatic rust way.
perhaps can have separate traits , implement 1 implementers of other:
struct concretetype; struct commontype; trait handler<input, output = input> { fn handle_event(&self, msg: &input) -> output; } trait handlertomessage<m> { fn decode(&self, msg: &concretetype) -> m; } impl<t, m> handler<concretetype, m> t t: handlertomessage<m> { fn handle_event(&self, msg: &concretetype) -> m { self.decode(msg) } } impl handlertomessage<commontype> () { fn decode(&self, _msg: &concretetype) -> commontype { unimplemented!() } } fn main() {}
the last 1 awkward because you'd implement trait concrete type, haven't presented make sense implement for.
Comments
Post a Comment