feat(forge): add safe stringers for core value types
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
0dd5916f4e
commit
36f9619fc4
4 changed files with 199 additions and 0 deletions
81
ax_stringer_test.go
Normal file
81
ax_stringer_test.go
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
package forge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParams_String_Good(t *testing.T) {
|
||||
params := Params{"repo": "go-forge", "owner": "core"}
|
||||
want := `forge.Params{owner="core", repo="go-forge"}`
|
||||
if got := params.String(); got != want {
|
||||
t.Fatalf("got String()=%q, want %q", got, want)
|
||||
}
|
||||
if got := fmt.Sprint(params); got != want {
|
||||
t.Fatalf("got fmt.Sprint=%q, want %q", got, want)
|
||||
}
|
||||
if got := fmt.Sprintf("%#v", params); got != want {
|
||||
t.Fatalf("got GoString=%q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParams_String_NilSafe(t *testing.T) {
|
||||
var params Params
|
||||
want := "forge.Params{<nil>}"
|
||||
if got := params.String(); got != want {
|
||||
t.Fatalf("got String()=%q, want %q", got, want)
|
||||
}
|
||||
if got := fmt.Sprint(params); got != want {
|
||||
t.Fatalf("got fmt.Sprint=%q, want %q", got, want)
|
||||
}
|
||||
if got := fmt.Sprintf("%#v", params); got != want {
|
||||
t.Fatalf("got GoString=%q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListOptions_String_Good(t *testing.T) {
|
||||
opts := ListOptions{Page: 2, Limit: 25}
|
||||
want := "forge.ListOptions{page=2, limit=25}"
|
||||
if got := opts.String(); got != want {
|
||||
t.Fatalf("got String()=%q, want %q", got, want)
|
||||
}
|
||||
if got := fmt.Sprint(opts); got != want {
|
||||
t.Fatalf("got fmt.Sprint=%q, want %q", got, want)
|
||||
}
|
||||
if got := fmt.Sprintf("%#v", opts); got != want {
|
||||
t.Fatalf("got GoString=%q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateLimit_String_Good(t *testing.T) {
|
||||
rl := RateLimit{Limit: 80, Remaining: 79, Reset: 1700000003}
|
||||
want := "forge.RateLimit{limit=80, remaining=79, reset=1700000003}"
|
||||
if got := rl.String(); got != want {
|
||||
t.Fatalf("got String()=%q, want %q", got, want)
|
||||
}
|
||||
if got := fmt.Sprint(rl); got != want {
|
||||
t.Fatalf("got fmt.Sprint=%q, want %q", got, want)
|
||||
}
|
||||
if got := fmt.Sprintf("%#v", rl); got != want {
|
||||
t.Fatalf("got GoString=%q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPagedResult_String_Good(t *testing.T) {
|
||||
page := PagedResult[int]{
|
||||
Items: []int{1, 2, 3},
|
||||
TotalCount: 10,
|
||||
Page: 2,
|
||||
HasMore: true,
|
||||
}
|
||||
want := "forge.PagedResult{items=3, totalCount=10, page=2, hasMore=true}"
|
||||
if got := page.String(); got != want {
|
||||
t.Fatalf("got String()=%q, want %q", got, want)
|
||||
}
|
||||
if got := fmt.Sprint(page); got != want {
|
||||
t.Fatalf("got fmt.Sprint=%q, want %q", got, want)
|
||||
}
|
||||
if got := fmt.Sprintf("%#v", page); got != want {
|
||||
t.Fatalf("got GoString=%q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
25
client.go
25
client.go
|
|
@ -109,6 +109,31 @@ type RateLimit struct {
|
|||
Reset int64
|
||||
}
|
||||
|
||||
// String returns a safe summary of the rate limit state.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// rl := client.RateLimit()
|
||||
// _ = rl.String()
|
||||
func (r RateLimit) String() string {
|
||||
return core.Concat(
|
||||
"forge.RateLimit{limit=",
|
||||
strconv.Itoa(r.Limit),
|
||||
", remaining=",
|
||||
strconv.Itoa(r.Remaining),
|
||||
", reset=",
|
||||
strconv.FormatInt(r.Reset, 10),
|
||||
"}",
|
||||
)
|
||||
}
|
||||
|
||||
// GoString returns a safe Go-syntax summary of the rate limit state.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// _ = fmt.Sprintf("%#v", client.RateLimit())
|
||||
func (r RateLimit) GoString() string { return r.String() }
|
||||
|
||||
// Client is a low-level HTTP client for the Forgejo API.
|
||||
//
|
||||
// Usage:
|
||||
|
|
|
|||
|
|
@ -23,6 +23,28 @@ type ListOptions struct {
|
|||
Limit int // items per page (default 50)
|
||||
}
|
||||
|
||||
// String returns a safe summary of the pagination options.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// _ = forge.DefaultList.String()
|
||||
func (o ListOptions) String() string {
|
||||
return core.Concat(
|
||||
"forge.ListOptions{page=",
|
||||
strconv.Itoa(o.Page),
|
||||
", limit=",
|
||||
strconv.Itoa(o.Limit),
|
||||
"}",
|
||||
)
|
||||
}
|
||||
|
||||
// GoString returns a safe Go-syntax summary of the pagination options.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// _ = fmt.Sprintf("%#v", forge.DefaultList)
|
||||
func (o ListOptions) GoString() string { return o.String() }
|
||||
|
||||
// DefaultList provides sensible default pagination.
|
||||
//
|
||||
// Usage:
|
||||
|
|
@ -44,6 +66,37 @@ type PagedResult[T any] struct {
|
|||
HasMore bool
|
||||
}
|
||||
|
||||
// String returns a safe summary of a page of results.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// page, _ := forge.ListPage[types.Repository](...)
|
||||
// _ = page.String()
|
||||
func (r PagedResult[T]) String() string {
|
||||
items := 0
|
||||
if r.Items != nil {
|
||||
items = len(r.Items)
|
||||
}
|
||||
return core.Concat(
|
||||
"forge.PagedResult{items=",
|
||||
strconv.Itoa(items),
|
||||
", totalCount=",
|
||||
strconv.Itoa(r.TotalCount),
|
||||
", page=",
|
||||
strconv.Itoa(r.Page),
|
||||
", hasMore=",
|
||||
strconv.FormatBool(r.HasMore),
|
||||
"}",
|
||||
)
|
||||
}
|
||||
|
||||
// GoString returns a safe Go-syntax summary of a page of results.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// _ = fmt.Sprintf("%#v", page)
|
||||
func (r PagedResult[T]) GoString() string { return r.String() }
|
||||
|
||||
// ListPage fetches a single page of results.
|
||||
// Extra query params can be passed via the query map.
|
||||
//
|
||||
|
|
|
|||
40
params.go
40
params.go
|
|
@ -2,6 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
)
|
||||
|
|
@ -15,6 +18,43 @@ import (
|
|||
// _ = params
|
||||
type Params map[string]string
|
||||
|
||||
// String returns a safe summary of the path parameters.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// _ = forge.Params{"owner": "core"}.String()
|
||||
func (p Params) String() string {
|
||||
if p == nil {
|
||||
return "forge.Params{<nil>}"
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(p))
|
||||
for k := range p {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
var b strings.Builder
|
||||
b.WriteString("forge.Params{")
|
||||
for i, k := range keys {
|
||||
if i > 0 {
|
||||
b.WriteString(", ")
|
||||
}
|
||||
b.WriteString(k)
|
||||
b.WriteString("=")
|
||||
b.WriteString(strconv.Quote(p[k]))
|
||||
}
|
||||
b.WriteString("}")
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// GoString returns a safe Go-syntax summary of the path parameters.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// _ = fmt.Sprintf("%#v", forge.Params{"owner": "core"})
|
||||
func (p Params) GoString() string { return p.String() }
|
||||
|
||||
// ResolvePath substitutes {placeholders} in path with values from params.
|
||||
//
|
||||
// Usage:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue