package peer import ( "github.com/go-faster/errors" "github.com/gotd/td/tg" ) // Entities is simple peer entities storage. type Entities struct { users map[int64]*tg.User chats map[int64]*tg.Chat channels map[int64]*tg.Channel } // NewEntities creates new Entities struct. func NewEntities( users map[int64]*tg.User, chats map[int64]*tg.Chat, channels map[int64]*tg.Channel, ) Entities { return Entities{users: users, chats: chats, channels: channels} } // EntitySearchResult is abstraction for different RPC responses which // contains entities. type EntitySearchResult interface { MapChats() tg.ChatClassArray MapUsers() tg.UserClassArray } // EntitiesFromResult fills Entities struct using given context. func EntitiesFromResult(r EntitySearchResult) Entities { return NewEntities( r.MapUsers().UserToMap(), r.MapChats().ChatToMap(), r.MapChats().ChannelToMap(), ) } // EntitiesFromUpdate fills Entities struct using given context. func EntitiesFromUpdate(uctx tg.Entities) Entities { return NewEntities( uctx.Users, uctx.Chats, uctx.Channels, ) } // Users returns map of users. // Notice that returned map is not a copy. func (ent Entities) Users() map[int64]*tg.User { return ent.users } // Chats returns map of chats. // Notice that returned map is not a copy. func (ent Entities) Chats() map[int64]*tg.Chat { return ent.chats } // Channels returns map of channels. // Notice that returned map is not a copy. func (ent Entities) Channels() map[int64]*tg.Channel { return ent.channels } // FillFromResult adds and updates all entities from given result. func (ent Entities) FillFromResult(r EntitySearchResult) { r.MapUsers().FillUserMap(ent.users) r.MapChats().FillChatMap(ent.chats) r.MapChats().FillChannelMap(ent.channels) } // FillFromUpdate adds and updates all entities from given updates. func (ent Entities) FillFromUpdate(uctx tg.Entities) { ent.Fill( uctx.Users, uctx.Chats, uctx.Channels, ) } // Fill adds and updates all entities from given maps. func (ent Entities) Fill( users map[int64]*tg.User, chats map[int64]*tg.Chat, channels map[int64]*tg.Channel, ) { for k, v := range users { ent.users[k] = v } for k, v := range chats { ent.chats[k] = v } for k, v := range channels { ent.channels[k] = v } } // ExtractPeer finds and creates InputPeerClass using given PeerClass. func (ent Entities) ExtractPeer(peerID tg.PeerClass) (tg.InputPeerClass, error) { var peer tg.InputPeerClass switch p := peerID.(type) { case *tg.PeerUser: // peerUser#9db1bc6d dialog, ok := ent.users[p.UserID] if !ok { return nil, errors.Errorf("user %d not found", p.UserID) } peer = &tg.InputPeerUser{ UserID: dialog.ID, AccessHash: dialog.AccessHash, } case *tg.PeerChat: // peerChat#bad0e5bb dialog, ok := ent.chats[p.ChatID] if !ok { return nil, errors.Errorf("chat %d not found", p.ChatID) } peer = &tg.InputPeerChat{ ChatID: dialog.ID, } case *tg.PeerChannel: // peerChannel#bddde532 dialog, ok := ent.channels[p.ChannelID] if !ok { return nil, errors.Errorf("channel %d not found", p.ChannelID) } peer = &tg.InputPeerChannel{ ChannelID: dialog.ID, AccessHash: dialog.AccessHash, } default: return nil, errors.Errorf("unexpected peer type %T", peerID) } return peer, nil } // User finds user by given ID. func (ent Entities) User(id int64) (*tg.User, bool) { v, ok := ent.users[id] return v, ok } // Chat finds chat by given ID. func (ent Entities) Chat(id int64) (*tg.Chat, bool) { v, ok := ent.chats[id] return v, ok } // Channel finds channel by given ID. func (ent Entities) Channel(id int64) (*tg.Channel, bool) { v, ok := ent.channels[id] return v, ok }