package tg import ( "context" "go.uber.org/multierr" ) type Handler = func(context.Context, Entities, UpdateClass) error type UpdateDispatcher struct { handlers map[uint32]Handler fallback Handler } func NewUpdateDispatcher() UpdateDispatcher { return UpdateDispatcher{ handlers: map[uint32]Handler{}, fallback: func(ctx context.Context, entities Entities, class UpdateClass) error { return nil }, } } type Entities struct { Short bool Users map[int64]*User Chats map[int64]*Chat Channels map[int64]*Channel } func (u *Entities) short() { u.Short = true u.Users = make(map[int64]*User, 0) u.Chats = make(map[int64]*Chat, 0) u.Channels = make(map[int64]*Channel, 0) } // Handle implements UpdateDispatcher. func (u UpdateDispatcher) Handle(ctx context.Context, updates UpdatesClass) error { var ( e Entities upds []UpdateClass ) switch u := updates.(type) { case *Updates: upds = u.Updates e.Users = u.MapUsers().NotEmptyToMap() chats := u.MapChats() e.Chats = chats.ChatToMap() e.Channels = chats.ChannelToMap() case *UpdatesCombined: upds = u.Updates e.Users = u.MapUsers().NotEmptyToMap() chats := u.MapChats() e.Chats = chats.ChatToMap() e.Channels = chats.ChannelToMap() case *UpdateShort: upds = []UpdateClass{u.Update} e.short() default: // *UpdateShortMessage // *UpdateShortChatMessage // *UpdateShortSentMessage // *UpdatesTooLong return nil } var err error for _, update := range upds { multierr.AppendInto(&err, u.dispatch(ctx, e, update)) } return err } func (u UpdateDispatcher) dispatch(ctx context.Context, e Entities, update UpdateClass) error { if update == nil { return nil } if err := u.fallback(ctx, e, update); err != nil { return err } typeID := update.TypeID() handler, ok := u.handlers[typeID] if ok { return handler(ctx, e, update) } return nil }