feat(api): add api.Ptr helper for optional scalar fields

Telegram's optional int/bool/float fields are pointers so callers can
explicitly send false or 0 to override a chat default — distinct from
'absent', which uses the chat default. The pointer construction has been
ergonomically painful:

  photoLimit := int64(5)
  Limit: &photoLimit

api.Ptr[T any](v T) *T collapses that to a single line:

  Limit: api.Ptr[int64](5)
  DisableNotification: api.Ptr(true)

Pointers stay because the explicit-zero distinction matters for fields
like DisableNotification, ProtectContent, and getUpdates.Offset where
sending 0 / false explicitly is semantically different from omitting
the field.
This commit is contained in:
2026-05-09 18:01:28 +01:00
parent 3c04d7b0b1
commit e4614d800f
4 changed files with 86 additions and 0 deletions
+16
View File
@@ -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 }
+28
View File
@@ -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")
}
}