[rust-dev] Implementation inheritance or mixins

Patrick Walton pwalton at mozilla.com
Tue Dec 25 13:58:05 PST 2012


On 12/25/12 2:25 PM, Michael Neumann wrote:
> Hi,
>
> I am trying to switch over my msgpack implementation [1] to use the
> Encoder/Decoder trait from serialize.rs. I want to implement a basic
> encoder and a more optimized one (in terms of generated storage).
> Most of the emit_() functions will be shared between the two, just
> integers would be emitted based on their actual range and not depending
> on their type. Now my question is wheather I can reuse some code by
> using something like a Mixin?
>
> Is there something like this:
>
>    struct Encoder { ... }
>
>    pub impl Encoder : serialize::Encoder {
>      fn emit_nil ...
>      ...
>    }
>
>    struct OptEncoder { ... }
>
>    pub impl OptEncoder : serialize::Encoder {
>      include Encoder
>
>      fn emit_uint(...) { ... } // overwrite emit_uint
>    }
>
> Or how would you implement that?
>
> Actually what I want is some way to literally "include" some functions into
> the scope of an implementation (like a mixin). Similar in the way Ruby or
> Sather handles this.

Macros might be your best bet in terms of readability, but you can't 
have them expand into methods at the moment. (This should be fixed in 
the future.)

Using traits you could do something like:

     struct BaseEncoder { ... }
     struct Encoder(BaseEncoder);
     struct OptEncoder(BaseEncoder);

     trait EncoderMethods {
         fn get_base_encoder(&self) -> &self/BaseEncoder;
         fn do_emit_uint(...) { ... }
     }

     impl Encoder : EncoderMethods {
         fn get_base_encoder(&self) -> &self/BaseEncoder { &*self }
         fn do_emit_uint(...) {
             /* Encoder-specific impl of emit_uint */
         }
     }
     impl OptEncoder : EncoderMethods {
         fn get_base_encoder(&self) -> &self/BaseEncoder { &*self }
         fn do_emit_uint(...) {
             /* Encoder-specific impl of emit_uint */
         }
     }

     /* this is the magic implementation */
     impl<T:EncoderMethods> T : serialize::Encoder {
         fn emit_uint(...) {
             self.do_emit_uint(...)
         }
         fn emit_int(...) { self.get_base_encoder()... }
         // implement other shared methods here
     }

Patrick



More information about the Rust-dev mailing list