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.

114 lines
2.7 KiB

package peer
import (
"context"
"fmt"
"github.com/go-faster/errors"
"github.com/gotd/td/tg"
)
// PromiseDecorator is a decorator of peer promise.
type PromiseDecorator = func(Promise) Promise
// ConstraintError is a peer resolve constraint error.
type ConstraintError struct {
Expected string
Got tg.InputPeerClass
}
// Error implements error.
func (c *ConstraintError) Error() string {
return fmt.Sprintf("expected %q, got %T", c.Expected, c.Got)
}
func tryUnpackConstraint(p tg.InputPeerClass, resolveErr error) (tg.InputPeerClass, error) {
var constraintErr *ConstraintError
if errors.As(resolveErr, &constraintErr) {
return constraintErr.Got, nil
}
return p, resolveErr
}
// OnlyChannel returns Promise which returns error if resolved peer is not a channel.
func OnlyChannel(p Promise) Promise {
return func(ctx context.Context) (tg.InputPeerClass, error) {
resolved, err := tryUnpackConstraint(p(ctx))
if err != nil {
return nil, err
}
switch resolved.(type) {
case *tg.InputPeerChannel, *tg.InputPeerChannelFromMessage:
return resolved, nil
default:
return nil, &ConstraintError{
Expected: "channel",
Got: resolved,
}
}
}
}
// OnlyChat returns Promise which returns error if resolved peer is not a chat.
func OnlyChat(p Promise) Promise {
return func(ctx context.Context) (tg.InputPeerClass, error) {
resolved, err := tryUnpackConstraint(p(ctx))
if err != nil {
return nil, err
}
switch resolved.(type) {
case *tg.InputPeerChat:
return resolved, nil
default:
return nil, &ConstraintError{
Expected: "chat",
Got: resolved,
}
}
}
}
// OnlyUser returns Promise which returns error if resolved peer is not a user.
func OnlyUser(p Promise) Promise {
return func(ctx context.Context) (tg.InputPeerClass, error) {
resolved, err := tryUnpackConstraint(p(ctx))
if err != nil {
return nil, err
}
switch resolved.(type) {
case *tg.InputPeerUser, *tg.InputPeerUserFromMessage, *tg.InputPeerSelf:
return resolved, nil
default:
return nil, &ConstraintError{
Expected: "user",
Got: resolved,
}
}
}
}
// OnlyUserID returns Promise which returns error if resolved peer is not a user object with ID.
// Unlike OnlyUser, it returns error if resolved peer is tg.InputPeerSelf.
func OnlyUserID(p Promise) Promise {
return func(ctx context.Context) (tg.InputPeerClass, error) {
resolved, err := tryUnpackConstraint(p(ctx))
if err != nil {
return nil, err
}
switch resolved.(type) {
case *tg.InputPeerUser, *tg.InputPeerUserFromMessage:
return resolved, nil
default:
return nil, &ConstraintError{
Expected: "userID",
Got: resolved,
}
}
}
}