You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
3.6 KiB
160 lines
3.6 KiB
3 years ago
|
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
|
||
|
}
|