Skip to content

Commit

Permalink
Fixed empty bool & string issue for types
Browse files Browse the repository at this point in the history
  • Loading branch information
mymmrac committed Feb 7, 2023
1 parent f179fe7 commit 0ee7efc
Show file tree
Hide file tree
Showing 17 changed files with 134 additions and 155 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ More examples can be seen here:
- [Predicate as middleware](examples/middleware_with_predicates/main.go)
- [Update processor](examples/update_processor/main.go)
- [Message entities](examples/message_entity/main.go)
- [Empty values](examples/empty_values/main.go)
- [Multi bot webhook](examples/multi_bot_webhook/main.go)

</details>
Expand Down
21 changes: 6 additions & 15 deletions bot.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package telego

import (
"bytes"
"errors"
"fmt"
"reflect"
Expand All @@ -15,8 +14,7 @@ import (
)

const (
defaultBotAPIServer = "https://api.telegram.org"
defaultBotEmptyValue = "TELEGO_EMPTY_VALUE"
defaultBotAPIServer = "https://api.telegram.org"

tokenRegexp = `^\d{9,10}:[\w-]{35}$` //nolint:gosec

Expand Down Expand Up @@ -44,7 +42,6 @@ type Bot struct {

healthCheckRequested bool
warningAsErrors bool
replaceToEmpty string

longPollingContext *longPollingContext
webhookContext *webhookContext
Expand Down Expand Up @@ -95,13 +92,6 @@ func (b *Bot) Logger() Logger {
return b.log
}

// EmptyValue returns value that will be erased from all requests useful for things like SwitchInlineQuery in
// telego.InlineKeyboardButton that have empty string as valid parameter value
// Warning: Only works if at least one of the bot options, WithEmptyValues or WithCustomEmptyValues are used
func (b *Bot) EmptyValue() string {
return b.replaceToEmpty
}

// performRequest executes and parses response of method
func (b *Bot) performRequest(methodName string, parameters interface{}, vs ...interface{}) error {
resp, err := b.constructAndCallRequest(methodName, parameters)
Expand Down Expand Up @@ -170,10 +160,6 @@ func (b *Bot) constructAndCallRequest(methodName string, parameters interface{})
debugData := strings.TrimSuffix(debug.String(), "\n")
b.log.Debugf("API call to: %q, with data: %s", url, debugData)

if b.replaceToEmpty != "" {
data.Buffer = bytes.NewBuffer(bytes.ReplaceAll(data.Buffer.Bytes(), []byte(b.replaceToEmpty), []byte{}))
}

resp, err := b.api.Call(url, data)
if err != nil {
return nil, fmt.Errorf("request call: %w", err)
Expand Down Expand Up @@ -293,3 +279,8 @@ func logRequestWithFiles(debug strings.Builder, parameters map[string]string, fi
func Bool(value bool) *bool {
return &value
}

// String converts string value into a string pointer
func String(value string) *string {
return &value
}
43 changes: 4 additions & 39 deletions bot_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package telego

import (
"errors"
"fmt"
"net/http"
"os"
"strings"

"github.com/goccy/go-json"
"github.com/valyala/fasthttp"

"github.com/mymmrac/telego/telegoapi"
Expand Down Expand Up @@ -62,7 +60,7 @@ func WithDefaultLogger(debugMode, printErrors bool) BotOption {
}

// WithExtendedDefaultLogger configures default logger, replacer can be nil. Redefines existing logger.
// Note: Keep in mind that debug logs will include your bot token, it's only safe to have them enabled in
// Note: Keep in mind that debug logs will include your bot token. It's only safe to have them enabled in
// testing environment, or hide sensitive information (like bot token) yourself.
func WithExtendedDefaultLogger(debugMode, printErrors bool, replacer *strings.Replacer) BotOption {
return func(bot *Bot) error {
Expand All @@ -89,7 +87,7 @@ func WithDiscardLogger() BotOption {
}

// WithLogger sets logger to use. Redefines existing logger.
// Note: Keep in mind that debug logs will include your bot token, it's only safe to have them enabled in
// Note: Keep in mind that debug logs will include your bot token. It's only safe to have them enabled in
// testing environment, or hide sensitive information (like bot token) yourself.
func WithLogger(log Logger) BotOption {
return func(bot *Bot) error {
Expand Down Expand Up @@ -118,44 +116,11 @@ func WithHealthCheck() BotOption {
}
}

// WithWarnings treat Telegram warnings as errors
// Note: Any request that has non-empty error will return both result and error
// WithWarnings treat Telegram warnings as an error
// Note: Any request that has a non-empty error will return both result and error
func WithWarnings() BotOption {
return func(bot *Bot) error {
bot.warningAsErrors = true
return nil
}
}

// WithEmptyValues sets empty value to default one that will be erased from all requests
// Note: Used with Bot.EmptyValue() to get empty strings as parameters
func WithEmptyValues() BotOption {
return func(bot *Bot) error {
bot.replaceToEmpty = defaultBotEmptyValue
return nil
}
}

// WithCustomEmptyValues sets empty value to custom value that will be erased from all requests
// Note: Used with Bot.EmptyValue() to get empty strings as parameters values
// Warning: Request data is encoded using JSON, so the value will be escaped in JSON and may not match intended value
func WithCustomEmptyValues(emptyValue string) BotOption {
return func(bot *Bot) error {
if emptyValue == "" {
return fmt.Errorf("empty value can't be zero length")
}

data, err := json.Marshal(emptyValue)
if err != nil {
return fmt.Errorf("marshal empty value: %w", err)
}

if fmt.Sprintf(`"%s"`, emptyValue) != string(data) {
return fmt.Errorf(`empty value does't match it's JSON encoded varian: "%s" not equal to %s`,
emptyValue, string(data))
}

bot.replaceToEmpty = emptyValue
return nil
}
}
30 changes: 0 additions & 30 deletions bot_options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,33 +184,3 @@ func TestWithWarnings(t *testing.T) {

assert.True(t, bot.warningAsErrors)
}

func TestWithEmptyValues(t *testing.T) {
bot := &Bot{}

err := WithEmptyValues()(bot)
assert.NoError(t, err)

assert.Equal(t, defaultBotEmptyValue, bot.replaceToEmpty)
}

func TestWithCustomEmptyValues(t *testing.T) {
bot := &Bot{}

t.Run("success", func(t *testing.T) {
err := WithCustomEmptyValues(defaultBotEmptyValue)(bot)
assert.NoError(t, err)

assert.Equal(t, defaultBotEmptyValue, bot.replaceToEmpty)
})

t.Run("error_empty", func(t *testing.T) {
err := WithCustomEmptyValues("")(bot)
assert.Error(t, err)
})

t.Run("error_marshal_does_not_match", func(t *testing.T) {
err := WithCustomEmptyValues(string([]byte{1}))(bot)
assert.Error(t, err)
})
}
12 changes: 5 additions & 7 deletions bot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,6 @@ func TestBot_Logger(t *testing.T) {
assert.Equal(t, bot.log, bot.Logger())
}

func TestBot_EmptyValue(t *testing.T) {
bot, err := NewBot(token, WithEmptyValues())
assert.NoError(t, err)

assert.Equal(t, defaultBotEmptyValue, bot.EmptyValue())
}

type testErrorMarshal struct {
Number int `json:"number"`
}
Expand Down Expand Up @@ -663,3 +656,8 @@ func TestBool(t *testing.T) {
assert.True(t, *Bool(true))
assert.False(t, *Bool(false))
}

func TestString(t *testing.T) {
assert.Equal(t, "", *String(""))
assert.Equal(t, "a", *String("a"))
}
11 changes: 1 addition & 10 deletions examples/configuration/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func main() {
telego.WithHealthCheck(),

// Make all warnings an errors for all requests (default: false)
// Note: Things like `deleteWebhook` may return result as true, but also error description with warning
// Note: Things like `deleteWebhook` may return a result as true, but also error description with warning
telego.WithWarnings(),

// Configuration of default logger, enable printing debug information and errors (default: false, true)
Expand All @@ -54,15 +54,6 @@ func main() {
// Note: Please keep in mind that logger may expose sensitive information, use in development only or configure
// it not to leak unwanted content
telego.WithLogger(myLogger),

// Used in combination with telego.Bot.EmptyValue() to get empty values for string parameters in cases where
// empty parameter is a valid value (default: TELEGO_EMPTY_VALUE)
// Note: By default, no empty value is set, so using telego.Bot.EmptyValue() does nothing
telego.WithEmptyValues(),

// Same as telego.WithEmptyValues(), but you can define your own empty value that will be used
// Note: Request data will be encoded as JSON, so an empty value should match it after encoding too
telego.WithCustomEmptyValues("the_empty_value"),
)
if err != nil {
fmt.Println(err)
Expand Down
41 changes: 0 additions & 41 deletions examples/empty_values/main.go

This file was deleted.

2 changes: 2 additions & 0 deletions internal/generator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ func main() {

sr := sharedResources{}

// TODO: Add cases for *bool and *string

for _, arg := range args {
logInfo("==== %s ====", arg)
start := time.Now()
Expand Down
4 changes: 2 additions & 2 deletions internal/test/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func main() {
testToken := os.Getenv("TOKEN")

bot, err := telego.NewBot(testToken,
telego.WithDefaultDebugLogger(), telego.WithWarnings(), telego.WithEmptyValues())
telego.WithDefaultDebugLogger(), telego.WithWarnings())
if err != nil {
fmt.Println(err)
return
Expand Down Expand Up @@ -683,7 +683,7 @@ func main() {
tu.InlineKeyboard(
tu.InlineKeyboardRow(
tu.InlineKeyboardButton("OK").
WithSwitchInlineQueryCurrentChat(bot.EmptyValue()),
WithSwitchInlineQueryCurrentChat(""),
),
),
),
Expand Down
2 changes: 1 addition & 1 deletion methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -2298,7 +2298,7 @@ type EditForumTopicParams struct {
// getForumTopicIconStickers (https://core.telegram.org/bots/api#getforumtopiciconstickers) to get all allowed
// custom emoji identifiers. Pass an empty string to remove the icon. If not specified, the current icon will be
// kept
IconCustomEmojiID string `json:"icon_custom_emoji_id,omitempty"`
IconCustomEmojiID *string `json:"icon_custom_emoji_id,omitempty"`
}

// EditForumTopic - Use this method to edit name and icon of a topic in a forum supergroup chat. The bot must
Expand Down
2 changes: 1 addition & 1 deletion methods_setters.go
Original file line number Diff line number Diff line change
Expand Up @@ -1740,7 +1740,7 @@ func (p *EditForumTopicParams) WithName(name string) *EditForumTopicParams {

// WithIconCustomEmojiID adds icon custom emoji ID parameter
func (p *EditForumTopicParams) WithIconCustomEmojiID(iconCustomEmojiID string) *EditForumTopicParams {
p.IconCustomEmojiID = iconCustomEmojiID
p.IconCustomEmojiID = String(iconCustomEmojiID)
return p
}

Expand Down
2 changes: 1 addition & 1 deletion methods_setters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,7 @@ func TestEditForumTopicParams_Setters(t *testing.T) {
ChatID: ChatID{ID: 2},
MessageThreadID: 1,
Name: "Name",
IconCustomEmojiID: "IconCustomEmojiID",
IconCustomEmojiID: String("IconCustomEmojiID"),
}, e)
}

Expand Down
2 changes: 1 addition & 1 deletion telegoapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ type Caller interface {

// NamedReader represents a way to send files (or other data).
// Implemented by os.File.
// Note: Name method should return unique names for all files sent in one request.
// Note: Name method may be called multiple times and should return unique names for all files sent in one request.
//
// Warning: Since, for sending data (files) reader data will be copied, using the same reader multiple times as is
// will not work.
Expand Down
Loading

0 comments on commit 0ee7efc

Please sign in to comment.