diff --git a/README.md b/README.md index 7b059dc..42b83aa 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,25 @@ Run any example: `TELEGRAM_BOT_TOKEN=xxx go run ./examples/` | | [`polls`](examples/polls) | `sendPoll` and answer tally | | | [`payments`](examples/payments) | Invoice → pre-checkout → success | +## Optional fields + +Telegram marks many fields as optional. For optional **scalars** (int, bool, float) we use pointers so you can explicitly send `false` or `0` when the wire format needs to override a chat default. The `api.Ptr` helper keeps that ergonomic: + +```go +api.SendMessage(ctx, bot, &api.SendMessageParams{ + ChatID: api.ChatIDFromInt(chatID), + Text: "hi", + DisableNotification: api.Ptr(true), // type inferred +}) + +api.GetUserProfilePhotos(ctx, bot, &api.GetUserProfilePhotosParams{ + UserID: userID, + Limit: api.Ptr[int64](5), // explicit type for untyped literals +}) +``` + +Optional structs and slices are already nullable in Go — no helper needed. + ## Reference docs Full API reference is auto-generated from source comments and lives in [`docs/reference/`](docs/reference/README.md) — browse package by package on GitHub, or read it rendered at [go-telegram.raczylo.com](https://go-telegram.raczylo.com/) and [pkg.go.dev](https://pkg.go.dev/github.com/lukaszraczylo/go-telegram). diff --git a/api/ptr.go b/api/ptr.go new file mode 100644 index 0000000..848b7a2 --- /dev/null +++ b/api/ptr.go @@ -0,0 +1,16 @@ +package api + +// Ptr returns a pointer to v. Useful for optional scalar fields where +// the wire format must distinguish absent (nil) from an explicit zero +// value (e.g. DisableNotification: api.Ptr(false) to override the +// chat default). +// +// For untyped literals, supply the type parameter explicitly: +// +// Limit: api.Ptr[int64](5) +// +// For already-typed values, type inference handles it: +// +// var n int64 = 5 +// Limit: api.Ptr(n) +func Ptr[T any](v T) *T { return &v } diff --git a/api/ptr_test.go b/api/ptr_test.go new file mode 100644 index 0000000..257ebc1 --- /dev/null +++ b/api/ptr_test.go @@ -0,0 +1,28 @@ +package api_test + +import ( + "testing" + + "github.com/lukaszraczylo/go-telegram/api" +) + +func TestPtr(t *testing.T) { + if got := api.Ptr[int64](5); got == nil || *got != 5 { + t.Fatalf("Ptr[int64](5) = %v, want *5", got) + } + if got := api.Ptr(false); got == nil || *got != false { + t.Fatalf("Ptr(false) = %v, want *false", got) + } + if got := api.Ptr("hello"); got == nil || *got != "hello" { + t.Fatalf("Ptr(\"hello\") = %v, want *\"hello\"", got) + } + + n := int64(42) + got := api.Ptr(n) + if got == nil || *got != 42 { + t.Fatalf("Ptr(n) = %v, want *42", got) + } + if got == &n { + t.Fatalf("Ptr should copy, not alias caller's variable") + } +} diff --git a/docs/reference/api.md b/docs/reference/api.md index e9d800b..ea129bc 100644 --- a/docs/reference/api.md +++ b/docs/reference/api.md @@ -59,6 +59,7 @@ Package api contains the Telegram Bot API object types and method wrappers, gene - [func LogOut\(ctx context.Context, b \*client.Bot, p \*LogOutParams\) \(bool, error\)](<#LogOut>) - [func PinChatMessage\(ctx context.Context, b \*client.Bot, p \*PinChatMessageParams\) \(bool, error\)](<#PinChatMessage>) - [func PromoteChatMember\(ctx context.Context, b \*client.Bot, p \*PromoteChatMemberParams\) \(bool, error\)](<#PromoteChatMember>) +- [func Ptr\[T any\]\(v T\) \*T](<#Ptr>) - [func ReadBusinessMessage\(ctx context.Context, b \*client.Bot, p \*ReadBusinessMessageParams\) \(bool, error\)](<#ReadBusinessMessage>) - [func RefundStarPayment\(ctx context.Context, b \*client.Bot, p \*RefundStarPaymentParams\) \(bool, error\)](<#RefundStarPayment>) - [func RemoveBusinessAccountProfilePhoto\(ctx context.Context, b \*client.Bot, p \*RemoveBusinessAccountProfilePhotoParams\) \(bool, error\)](<#RemoveBusinessAccountProfilePhoto>) @@ -1315,6 +1316,28 @@ PromoteChatMember calls the promoteChatMember Telegram Bot API method. Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Pass False for all boolean parameters to demote a user. Returns True on success. + +## func Ptr + +```go +func Ptr[T any](v T) *T +``` + +Ptr returns a pointer to v. Useful for optional scalar fields where the wire format must distinguish absent \(nil\) from an explicit zero value \(e.g. DisableNotification: api.Ptr\(false\) to override the chat default\). + +For untyped literals, supply the type parameter explicitly: + +``` +Limit: api.Ptr[int64](5) +``` + +For already\-typed values, type inference handles it: + +``` +var n int64 = 5 +Limit: api.Ptr(n) +``` + ## func ReadBusinessMessage