package yu_proto_old import ( "encoding" ) var generators = newInterfaceRegistry() // InterfaceMarshaler is used to differentiate implementations of an // interface when encoding/decoding type InterfaceMarshaler interface { encoding.BinaryMarshaler MarshalID() [8]byte } // InterfaceGeneratorFunc generates an instance of the implementation // of an interface type InterfaceGeneratorFunc func() interface{} // GeneratorID is the key used to map the generator functions type GeneratorID [8]byte type generatorRegistry struct { generators map[GeneratorID]InterfaceGeneratorFunc } func newInterfaceRegistry() *generatorRegistry { return &generatorRegistry{ generators: make(map[GeneratorID]InterfaceGeneratorFunc), } } // register gets the type tag and map it to the generator function func (ir *generatorRegistry) register(g InterfaceGeneratorFunc) { val, ok := g().(InterfaceMarshaler) if !ok { panic("Implementation of the interface must fulfilled InterfaceMarshaler") } key := val.MarshalID() ir.generators[key] = g } // get returns the generator associated with the tag func (ir *generatorRegistry) get(key GeneratorID) InterfaceGeneratorFunc { g, _ := ir.generators[key] return g } // RegisterInterface registers the generator to be used to decode // the type generated by the function func RegisterInterface(f InterfaceGeneratorFunc) { generators.register(f) }