Compare commits
No commits in common. "1286338af0c4be6229c302601a14077612446fd2" and "2302aa7ff8134ff9a514b760afe7cf087dfa96a3" have entirely different histories.
1286338af0
...
2302aa7ff8
|
@ -2,17 +2,11 @@ package reload
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fthvgb1/wp-go/helper/number"
|
"github.com/fthvgb1/wp-go/helper/number"
|
||||||
"github.com/fthvgb1/wp-go/helper/slice"
|
|
||||||
"github.com/fthvgb1/wp-go/safety"
|
"github.com/fthvgb1/wp-go/safety"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type queue struct {
|
var calls []func()
|
||||||
fn func()
|
|
||||||
order float64
|
|
||||||
}
|
|
||||||
|
|
||||||
var calls []queue
|
|
||||||
|
|
||||||
var anyMap = safety.NewMap[string, any]()
|
var anyMap = safety.NewMap[string, any]()
|
||||||
|
|
||||||
|
@ -53,7 +47,7 @@ func GetAnyMapFnBys[K comparable, V, A any](namespace string, fn func(A) V) func
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func safetyMapFn[K comparable, V, A any](namespace string, order ...float64) *safetyMap[K, V, A] {
|
func safetyMapFn[K comparable, V, A any](namespace string) *safetyMap[K, V, A] {
|
||||||
vv, ok := safetyMaps.Load(namespace)
|
vv, ok := safetyMaps.Load(namespace)
|
||||||
var m *safetyMap[K, V, A]
|
var m *safetyMap[K, V, A]
|
||||||
if ok {
|
if ok {
|
||||||
|
@ -67,7 +61,7 @@ func safetyMapFn[K comparable, V, A any](namespace string, order ...float64) *sa
|
||||||
m = &safetyMap[K, V, A]{safety.NewMap[K, V](), sync.Mutex{}}
|
m = &safetyMap[K, V, A]{safety.NewMap[K, V](), sync.Mutex{}}
|
||||||
Push(func() {
|
Push(func() {
|
||||||
m.val.Flush()
|
m.val.Flush()
|
||||||
}, order...)
|
})
|
||||||
safetyMaps.Store(namespace, m)
|
safetyMaps.Store(namespace, m)
|
||||||
}
|
}
|
||||||
safetyMapLock.Unlock()
|
safetyMapLock.Unlock()
|
||||||
|
@ -75,8 +69,8 @@ func safetyMapFn[K comparable, V, A any](namespace string, order ...float64) *sa
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAnyValMapBy[K comparable, V, A any](namespace string, key K, a A, fn func(A) V, order ...float64) V {
|
func GetAnyValMapBy[K comparable, V, A any](namespace string, key K, a A, fn func(A) V) V {
|
||||||
m := safetyMapFn[K, V, A](namespace, order...)
|
m := safetyMapFn[K, V, A](namespace)
|
||||||
v, ok := m.val.Load(key)
|
v, ok := m.val.Load(key)
|
||||||
if ok {
|
if ok {
|
||||||
return v
|
return v
|
||||||
|
@ -93,7 +87,7 @@ func GetAnyValMapBy[K comparable, V, A any](namespace string, key K, a A, fn fun
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func anyVal[T, A any](namespace string, counter bool, order ...float64) *safetyVar[T, A] {
|
func anyVal[T, A any](namespace string, counter bool) *safetyVar[T, A] {
|
||||||
var vv *safetyVar[T, A]
|
var vv *safetyVar[T, A]
|
||||||
vvv, ok := safetyMaps.Load(namespace)
|
vvv, ok := safetyMaps.Load(namespace)
|
||||||
if ok {
|
if ok {
|
||||||
|
@ -111,7 +105,7 @@ func anyVal[T, A any](namespace string, counter bool, order ...float64) *safetyV
|
||||||
vv = &safetyVar[T, A]{safety.NewVar(v), sync.Mutex{}}
|
vv = &safetyVar[T, A]{safety.NewVar(v), sync.Mutex{}}
|
||||||
Push(func() {
|
Push(func() {
|
||||||
vv.Val.Flush()
|
vv.Val.Flush()
|
||||||
}, getOrder(order...))
|
})
|
||||||
safetyMaps.Store(namespace, vv)
|
safetyMaps.Store(namespace, vv)
|
||||||
}
|
}
|
||||||
safetyMapLock.Unlock()
|
safetyMapLock.Unlock()
|
||||||
|
@ -119,8 +113,8 @@ func anyVal[T, A any](namespace string, counter bool, order ...float64) *safetyV
|
||||||
return vv
|
return vv
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAnyValBy[T, A any](namespace string, tryTimes int, a A, fn func(A) (T, bool), order ...float64) T {
|
func GetAnyValBy[T, A any](namespace string, tryTimes int, a A, fn func(A) (T, bool)) T {
|
||||||
var vv = anyVal[T, A](namespace, true, order...)
|
var vv = anyVal[T, A](namespace, true)
|
||||||
var ok bool
|
var ok bool
|
||||||
v := vv.Val.Load()
|
v := vv.Val.Load()
|
||||||
if v.ok {
|
if v.ok {
|
||||||
|
@ -142,8 +136,8 @@ func GetAnyValBy[T, A any](namespace string, tryTimes int, a A, fn func(A) (T, b
|
||||||
return v.v
|
return v.v
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAnyValBys[T, A any](namespace string, a A, fn func(A) T, order ...float64) T {
|
func GetAnyValBys[T, A any](namespace string, a A, fn func(A) T) T {
|
||||||
var vv = anyVal[T, A](namespace, false, order...)
|
var vv = anyVal[T, A](namespace, false)
|
||||||
v := vv.Val.Load()
|
v := vv.Val.Load()
|
||||||
if v.ok {
|
if v.ok {
|
||||||
return v.v
|
return v.v
|
||||||
|
@ -161,69 +155,49 @@ func GetAnyValBys[T, A any](namespace string, a A, fn func(A) T, order ...float6
|
||||||
return v.v
|
return v.v
|
||||||
}
|
}
|
||||||
|
|
||||||
func Vars[T any](defaults T, order ...float64) *safety.Var[T] {
|
func Vars[T any](defaults T) *safety.Var[T] {
|
||||||
ss := safety.NewVar(defaults)
|
ss := safety.NewVar(defaults)
|
||||||
ord := getOrder(order...)
|
calls = append(calls, func() {
|
||||||
calls = append(calls, queue{func() {
|
|
||||||
ss.Store(defaults)
|
ss.Store(defaults)
|
||||||
}, ord})
|
|
||||||
return ss
|
|
||||||
}
|
|
||||||
|
|
||||||
func getOrder(order ...float64) float64 {
|
|
||||||
var ord float64
|
|
||||||
if len(order) > 0 {
|
|
||||||
ord = order[0]
|
|
||||||
}
|
|
||||||
return ord
|
|
||||||
}
|
|
||||||
func VarsBy[T any](fn func() T, order ...float64) *safety.Var[T] {
|
|
||||||
ss := safety.NewVar(fn())
|
|
||||||
ord := getOrder(order...)
|
|
||||||
calls = append(calls, queue{
|
|
||||||
func() {
|
|
||||||
ss.Store(fn())
|
|
||||||
}, ord,
|
|
||||||
})
|
})
|
||||||
return ss
|
return ss
|
||||||
}
|
}
|
||||||
func MapBy[K comparable, T any](fn func(*safety.Map[K, T]), order ...float64) *safety.Map[K, T] {
|
func VarsBy[T any](fn func() T) *safety.Var[T] {
|
||||||
|
ss := safety.NewVar(fn())
|
||||||
|
calls = append(calls, func() {
|
||||||
|
ss.Store(fn())
|
||||||
|
})
|
||||||
|
return ss
|
||||||
|
}
|
||||||
|
func MapBy[K comparable, T any](fn func(*safety.Map[K, T])) *safety.Map[K, T] {
|
||||||
m := safety.NewMap[K, T]()
|
m := safety.NewMap[K, T]()
|
||||||
if fn != nil {
|
if fn != nil {
|
||||||
fn(m)
|
fn(m)
|
||||||
}
|
}
|
||||||
ord := getOrder(order...)
|
calls = append(calls, func() {
|
||||||
calls = append(calls, queue{
|
m.Flush()
|
||||||
func() {
|
if fn != nil {
|
||||||
m.Flush()
|
fn(m)
|
||||||
if fn != nil {
|
}
|
||||||
fn(m)
|
|
||||||
}
|
|
||||||
}, ord,
|
|
||||||
})
|
})
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func SafeMap[K comparable, T any](order ...float64) *safety.Map[K, T] {
|
func SafeMap[K comparable, T any]() *safety.Map[K, T] {
|
||||||
m := safety.NewMap[K, T]()
|
m := safety.NewMap[K, T]()
|
||||||
ord := getOrder(order...)
|
calls = append(calls, func() {
|
||||||
calls = append(calls, queue{func() {
|
|
||||||
m.Flush()
|
m.Flush()
|
||||||
}, ord})
|
})
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func Push(fn func(), order ...float64) {
|
func Push(fn ...func()) {
|
||||||
ord := getOrder(order...)
|
calls = append(calls, fn...)
|
||||||
calls = append(calls, queue{fn, ord})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Reload() {
|
func Reload() {
|
||||||
slice.Sort(calls, func(i, j queue) bool {
|
|
||||||
return i.order > j.order
|
|
||||||
})
|
|
||||||
for _, call := range calls {
|
for _, call := range calls {
|
||||||
call.fn()
|
call()
|
||||||
}
|
}
|
||||||
anyMap.Flush()
|
anyMap.Flush()
|
||||||
safetyMaps.Flush()
|
safetyMaps.Flush()
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var digestCache *cache.MapCache[uint64, string]
|
var digestCache *cache.MapCache[uint64, string]
|
||||||
|
@ -53,10 +52,6 @@ func Digests(content string, id uint64, limit int, fn func(id uint64, content, c
|
||||||
tag = "<a><b><blockquote><br><cite><code><dd><del><div><dl><dt><em><h1><h2><h3><h4><h5><h6><i><img><li><ol><p><pre><span><strong><ul>"
|
tag = "<a><b><blockquote><br><cite><code><dd><del><div><dl><dt><em><h1><h2><h3><h4><h5><h6><i><img><li><ol><p><pre><span><strong><ul>"
|
||||||
}
|
}
|
||||||
content = digest.StripTags(content, tag)
|
content = digest.StripTags(content, tag)
|
||||||
length := utf8.RuneCountInString(content) + 1
|
|
||||||
if length <= limit {
|
|
||||||
return content
|
|
||||||
}
|
|
||||||
content, closeTag = digest.Html(content, limit)
|
content, closeTag = digest.Html(content, limit)
|
||||||
if fn == nil {
|
if fn == nil {
|
||||||
return PostsMore(id, content, closeTag)
|
return PostsMore(id, content, closeTag)
|
||||||
|
|
|
@ -126,11 +126,3 @@ func FileExist(path string) bool {
|
||||||
_, err := os.Stat(path)
|
_, err := os.Stat(path)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAnyVal[T any](v any, defaults T) T {
|
|
||||||
vv, ok := v.(T)
|
|
||||||
if !ok {
|
|
||||||
return defaults
|
|
||||||
}
|
|
||||||
return vv
|
|
||||||
}
|
|
||||||
|
|
|
@ -267,16 +267,3 @@ func TestGetValFromContext(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetAnyVal(t *testing.T) {
|
|
||||||
t.Run("string", func(t *testing.T) {
|
|
||||||
want := "string"
|
|
||||||
if got := GetAnyVal(any("string"), "s"); !reflect.DeepEqual(got, want) {
|
|
||||||
t.Errorf("GetAnyVal() = %v, want %v", got, want)
|
|
||||||
}
|
|
||||||
want = "s"
|
|
||||||
if got := GetAnyVal(any(1), "s"); !reflect.DeepEqual(got, want) {
|
|
||||||
t.Errorf("GetAnyVal() = %v, want %v", got, want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,348 +0,0 @@
|
||||||
package httptool
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/fthvgb1/wp-go/helper/maps"
|
|
||||||
"github.com/fthvgb1/wp-go/helper/number"
|
|
||||||
str "github.com/fthvgb1/wp-go/helper/strings"
|
|
||||||
"golang.org/x/exp/constraints"
|
|
||||||
"io"
|
|
||||||
"mime/multipart"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetString(u string, q map[string]any, a ...any) (r string, code int, err error) {
|
|
||||||
res, err := Get(u, q, a...)
|
|
||||||
if res != nil {
|
|
||||||
code = res.StatusCode
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return "", code, err
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
rr, err := io.ReadAll(res.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", code, err
|
|
||||||
}
|
|
||||||
r = string(rr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Get(u string, q map[string]any, a ...any) (res *http.Response, err error) {
|
|
||||||
cli, req, err := GetClient(u, q, a...)
|
|
||||||
res, err = cli.Do(req)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetToJsonAny[T any](u string, q map[string]any, a ...any) (r T, code int, err error) {
|
|
||||||
rr, err := Get(u, q, a...)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
code = rr.StatusCode
|
|
||||||
b, err := io.ReadAll(rr.Body)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
rr.Body.Close()
|
|
||||||
err = json.Unmarshal(b, &r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func PostWwwString(u string, form map[string]any, a ...any) (r string, code int, err error) {
|
|
||||||
rr, err := Post(u, 1, form, a...)
|
|
||||||
if err != nil {
|
|
||||||
return "", 0, err
|
|
||||||
}
|
|
||||||
code = rr.StatusCode
|
|
||||||
rs, err := io.ReadAll(rr.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", code, err
|
|
||||||
}
|
|
||||||
rr.Body.Close()
|
|
||||||
r = string(rs)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func PostFormDataString(u string, form map[string]any, a ...any) (r string, code int, err error) {
|
|
||||||
rr, err := Post(u, 2, form, a...)
|
|
||||||
if err != nil {
|
|
||||||
return "", 0, err
|
|
||||||
}
|
|
||||||
code = rr.StatusCode
|
|
||||||
rs, err := io.ReadAll(rr.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", code, err
|
|
||||||
}
|
|
||||||
rr.Body.Close()
|
|
||||||
r = string(rs)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetClient(u string, q map[string]any, a ...any) (res *http.Client, req *http.Request, err error) {
|
|
||||||
parse, err := url.Parse(u)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
cli := http.Client{}
|
|
||||||
values := parse.Query()
|
|
||||||
setValue(q, values)
|
|
||||||
parse.RawQuery = values.Encode()
|
|
||||||
req = &http.Request{
|
|
||||||
Method: "GET",
|
|
||||||
URL: parse,
|
|
||||||
}
|
|
||||||
setArgs(&cli, req, a...)
|
|
||||||
return &cli, req, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Post request
|
|
||||||
//
|
|
||||||
// u url
|
|
||||||
//
|
|
||||||
// types 1 x-www-form-urlencoded, 2 form-data, 3 json, 4 binary
|
|
||||||
func Post(u string, types int, form map[string]any, a ...any) (res *http.Response, err error) {
|
|
||||||
cli, req, err := PostClient(u, types, form, a...)
|
|
||||||
res, err = cli.Do(req)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func PostClient(u string, types int, form map[string]any, a ...any) (cli *http.Client, req *http.Request, err error) {
|
|
||||||
parse, err := url.Parse(u)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cli = &http.Client{}
|
|
||||||
req = &http.Request{
|
|
||||||
Method: "POST",
|
|
||||||
URL: parse,
|
|
||||||
Header: http.Header{},
|
|
||||||
}
|
|
||||||
switch types {
|
|
||||||
case 1:
|
|
||||||
values := url.Values{}
|
|
||||||
setValue(form, values)
|
|
||||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
b := strings.NewReader(values.Encode())
|
|
||||||
req.Body = io.NopCloser(b)
|
|
||||||
case 2:
|
|
||||||
payload := &bytes.Buffer{}
|
|
||||||
writer := multipart.NewWriter(payload)
|
|
||||||
err = setFormData(form, writer)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = writer.Close()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
req.Body = io.NopCloser(payload)
|
|
||||||
req.Header.Add("Content-Type", writer.FormDataContentType())
|
|
||||||
case 3:
|
|
||||||
fo, err := json.Marshal(form)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
b := bytes.NewReader(fo)
|
|
||||||
req.Body = io.NopCloser(b)
|
|
||||||
req.Header.Add("Content-Type", "application/json")
|
|
||||||
case 4:
|
|
||||||
b, ok := maps.GetStrAnyVal[[]byte](form, "binary")
|
|
||||||
if !ok {
|
|
||||||
return nil, nil, errors.New("no binary value")
|
|
||||||
}
|
|
||||||
req.Body = io.NopCloser(bytes.NewReader(b))
|
|
||||||
req.Header.Add("Content-Type", "application/octet-stream")
|
|
||||||
}
|
|
||||||
setArgs(cli, req, a...)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func PostToJsonAny[T any](u string, types int, form map[string]any, a ...any) (r T, code int, err error) {
|
|
||||||
rr, err := Post(u, types, form, a...)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
code = rr.StatusCode
|
|
||||||
b, err := io.ReadAll(rr.Body)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
rr.Body.Close()
|
|
||||||
err = json.Unmarshal(b, &r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func setArgs(cli *http.Client, req *http.Request, a ...any) {
|
|
||||||
if len(a) < 1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, arg := range a {
|
|
||||||
h, ok := arg.(map[string]string)
|
|
||||||
if ok && len(h) > 0 {
|
|
||||||
for k, v := range h {
|
|
||||||
req.Header.Add(k, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hh, ok := arg.(http.Header)
|
|
||||||
if ok {
|
|
||||||
req.Header = hh
|
|
||||||
}
|
|
||||||
t, ok := arg.(time.Duration)
|
|
||||||
if ok {
|
|
||||||
cli.Timeout = t
|
|
||||||
}
|
|
||||||
checkRedirect, ok := arg.(func(req *http.Request, via []*http.Request) error)
|
|
||||||
if ok {
|
|
||||||
cli.CheckRedirect = checkRedirect
|
|
||||||
}
|
|
||||||
jar, ok := arg.(http.CookieJar)
|
|
||||||
if ok {
|
|
||||||
cli.Jar = jar
|
|
||||||
}
|
|
||||||
c, ok := arg.(string)
|
|
||||||
if ok && c != "" {
|
|
||||||
req.Header.Add("cookie", c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func set[T constraints.Integer | constraints.Float](a []T, k string, values url.Values) {
|
|
||||||
if !strings.Contains(k, "[]") {
|
|
||||||
k = str.Join(k, "[]")
|
|
||||||
}
|
|
||||||
for _, vv := range a {
|
|
||||||
values.Add(k, number.ToString(vv))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setFormData(m map[string]any, values *multipart.Writer) (err error) {
|
|
||||||
for k, v := range m {
|
|
||||||
switch v.(type) {
|
|
||||||
case *os.File:
|
|
||||||
f := v.(*os.File)
|
|
||||||
if f == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ff, err := values.CreateFormFile(k, f.Name())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = io.Copy(ff, f)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
case string:
|
|
||||||
err = values.WriteField(k, v.(string))
|
|
||||||
case int64, int, int8, int32, int16, uint64, uint, uint8, uint32, uint16, float32, float64:
|
|
||||||
err = values.WriteField(k, fmt.Sprintf("%v", v))
|
|
||||||
case []string:
|
|
||||||
if !strings.Contains(k, "[]") {
|
|
||||||
k = str.Join(k, "[]")
|
|
||||||
}
|
|
||||||
for _, vv := range v.([]string) {
|
|
||||||
err = values.WriteField(k, vv)
|
|
||||||
}
|
|
||||||
case *[]string:
|
|
||||||
if !strings.Contains(k, "[]") {
|
|
||||||
k = str.Join(k, "[]")
|
|
||||||
}
|
|
||||||
for _, vv := range *(v.(*[]string)) {
|
|
||||||
err = values.WriteField(k, vv)
|
|
||||||
}
|
|
||||||
case []int64:
|
|
||||||
err = sets(v.([]int64), k, values)
|
|
||||||
case []int:
|
|
||||||
err = sets(v.([]int), k, values)
|
|
||||||
case []int8:
|
|
||||||
err = sets(v.([]int8), k, values)
|
|
||||||
case []int16:
|
|
||||||
err = sets(v.([]int16), k, values)
|
|
||||||
case []int32:
|
|
||||||
err = sets(v.([]int32), k, values)
|
|
||||||
case []uint64:
|
|
||||||
err = sets(v.([]uint64), k, values)
|
|
||||||
case []uint:
|
|
||||||
err = sets(v.([]uint), k, values)
|
|
||||||
case []uint8:
|
|
||||||
err = sets(v.([]uint8), k, values)
|
|
||||||
case []uint16:
|
|
||||||
err = sets(v.([]uint16), k, values)
|
|
||||||
case []uint32:
|
|
||||||
err = sets(v.([]uint32), k, values)
|
|
||||||
case []float32:
|
|
||||||
err = sets(v.([]float32), k, values)
|
|
||||||
case []float64:
|
|
||||||
err = sets(v.([]float64), k, values)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func sets[T constraints.Integer | constraints.Float](a []T, k string, values *multipart.Writer) error {
|
|
||||||
if !strings.Contains(k, "[]") {
|
|
||||||
k = str.Join(k, "[]")
|
|
||||||
}
|
|
||||||
for _, vv := range a {
|
|
||||||
err := values.WriteField(k, number.ToString(vv))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setValue(m map[string]any, values url.Values) {
|
|
||||||
for k, v := range m {
|
|
||||||
switch v.(type) {
|
|
||||||
case string:
|
|
||||||
values.Add(k, v.(string))
|
|
||||||
case int64, int, int8, int32, int16, uint64, uint, uint8, uint32, uint16, float32, float64:
|
|
||||||
values.Add(k, fmt.Sprintf("%v", v))
|
|
||||||
case []string:
|
|
||||||
if !strings.Contains(k, "[]") {
|
|
||||||
k = str.Join(k, "[]")
|
|
||||||
}
|
|
||||||
for _, vv := range v.([]string) {
|
|
||||||
values.Add(k, vv)
|
|
||||||
}
|
|
||||||
case *[]string:
|
|
||||||
if !strings.Contains(k, "[]") {
|
|
||||||
k = str.Join(k, "[]")
|
|
||||||
}
|
|
||||||
for _, vv := range *(v.(*[]string)) {
|
|
||||||
values.Add(k, vv)
|
|
||||||
}
|
|
||||||
case []int64:
|
|
||||||
set(v.([]int64), k, values)
|
|
||||||
case []int:
|
|
||||||
set(v.([]int), k, values)
|
|
||||||
case []int8:
|
|
||||||
set(v.([]int8), k, values)
|
|
||||||
case []int16:
|
|
||||||
set(v.([]int16), k, values)
|
|
||||||
case []int32:
|
|
||||||
set(v.([]int32), k, values)
|
|
||||||
case []uint64:
|
|
||||||
set(v.([]uint64), k, values)
|
|
||||||
case []uint:
|
|
||||||
set(v.([]uint), k, values)
|
|
||||||
case []uint8:
|
|
||||||
set(v.([]uint8), k, values)
|
|
||||||
case []uint16:
|
|
||||||
set(v.([]uint16), k, values)
|
|
||||||
case []uint32:
|
|
||||||
set(v.([]uint32), k, values)
|
|
||||||
case []float32:
|
|
||||||
set(v.([]float32), k, values)
|
|
||||||
case []float64:
|
|
||||||
set(v.([]float64), k, values)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,255 +0,0 @@
|
||||||
package httptool
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetString(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
u string
|
|
||||||
q map[string]any
|
|
||||||
timeout int64
|
|
||||||
a []any
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantR string
|
|
||||||
wantCode int
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "wp.test",
|
|
||||||
args: args{
|
|
||||||
u: "http://wp.test",
|
|
||||||
q: map[string]any{
|
|
||||||
"p": "2",
|
|
||||||
"XDEBUG_SESSION_START": "34343",
|
|
||||||
"a": []int{2, 3},
|
|
||||||
},
|
|
||||||
timeout: 3,
|
|
||||||
},
|
|
||||||
wantR: `{"XDEBUG_SESSION_START":"34343","p":"2"}`,
|
|
||||||
wantCode: 200,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
gotR, gotCode, err := GetString(tt.args.u, tt.args.q, tt.args.a...)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("GetString() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if gotR != tt.wantR {
|
|
||||||
t.Errorf("GetString() gotR = %v, want %v", gotR, tt.wantR)
|
|
||||||
}
|
|
||||||
if gotCode != tt.wantCode {
|
|
||||||
t.Errorf("GetString() gotCode = %v, want %v", gotCode, tt.wantCode)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostWwwString(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
u string
|
|
||||||
form map[string]any
|
|
||||||
timeout int64
|
|
||||||
a []any
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantRes string
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "t1",
|
|
||||||
args: args{
|
|
||||||
u: "http://wp.test?XDEBUG_SESSION_START=34244",
|
|
||||||
form: map[string]any{
|
|
||||||
"aa": "bb",
|
|
||||||
"bb[]": []int{1, 2},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
gotRes, _, err := PostWwwString(tt.args.u, tt.args.form, tt.args.a...)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("Post() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(gotRes, tt.wantRes) {
|
|
||||||
t.Errorf("Post() gotRes = %v, want %v", gotRes, tt.wantRes)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPost(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
u string
|
|
||||||
types int
|
|
||||||
form map[string]any
|
|
||||||
timeout int64
|
|
||||||
a []any
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantRes *http.Response
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "form-data",
|
|
||||||
args: args{
|
|
||||||
u: "http://wp.test?XDEBUG_SESSION_START=3424",
|
|
||||||
types: 3,
|
|
||||||
form: map[string]any{
|
|
||||||
"ff": "xxxff",
|
|
||||||
},
|
|
||||||
timeout: 0,
|
|
||||||
a: nil,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "raw-json",
|
|
||||||
args: args{
|
|
||||||
u: "http://wp.test?XDEBUG_SESSION_START=3424",
|
|
||||||
types: 3,
|
|
||||||
form: map[string]any{
|
|
||||||
"ff": "xxxff",
|
|
||||||
"kk": 1,
|
|
||||||
},
|
|
||||||
timeout: 0,
|
|
||||||
a: nil,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "binary",
|
|
||||||
args: args{
|
|
||||||
u: "http://wp.test?XDEBUG_SESSION_START=3424",
|
|
||||||
types: 4,
|
|
||||||
form: map[string]any{
|
|
||||||
"binary": []byte("ssssskkkkkk"),
|
|
||||||
},
|
|
||||||
a: nil,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
gotRes, err := Post(tt.args.u, tt.args.types, tt.args.form, tt.args.a...)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("Post() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(gotRes, tt.wantRes) {
|
|
||||||
t.Errorf("Post() gotRes = %v, want %v", gotRes, tt.wantRes)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type res struct {
|
|
||||||
Code int `json:"Code,omitempty"`
|
|
||||||
Message string `json:"Message" json:"Message,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostToJsonAny(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
u string
|
|
||||||
types int
|
|
||||||
form map[string]any
|
|
||||||
a []any
|
|
||||||
}
|
|
||||||
type testCase[T any] struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantR T
|
|
||||||
wantCode int
|
|
||||||
wantErr bool
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := []testCase[res]{
|
|
||||||
{
|
|
||||||
name: "res",
|
|
||||||
args: args{
|
|
||||||
u: "http://wp.test?XDEBUG_SESSION_START=3424",
|
|
||||||
types: 1,
|
|
||||||
a: []any{3 * time.Second, map[string]string{"user-agent": "httptool"}},
|
|
||||||
},
|
|
||||||
wantR: res{
|
|
||||||
200, "ok",
|
|
||||||
},
|
|
||||||
wantCode: 200,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
gotR, gotCode, err := PostToJsonAny[res](tt.args.u, tt.args.types, tt.args.form, tt.args.a...)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("PostToJsonAny() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(gotR, tt.wantR) {
|
|
||||||
t.Errorf("PostToJsonAny() gotR = %v, want %v", gotR, tt.wantR)
|
|
||||||
}
|
|
||||||
if gotCode != tt.wantCode {
|
|
||||||
t.Errorf("PostToJsonAny() gotCode = %v, want %v", gotCode, tt.wantCode)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetToJsonAny(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
u string
|
|
||||||
q map[string]any
|
|
||||||
a []any
|
|
||||||
}
|
|
||||||
type testCase[T any] struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantR T
|
|
||||||
wantCode int
|
|
||||||
wantErr bool
|
|
||||||
}
|
|
||||||
tests := []testCase[res]{
|
|
||||||
{
|
|
||||||
name: "t1",
|
|
||||||
args: args{
|
|
||||||
u: "http://wp.test?XDEBUG_SESSION_START=3424",
|
|
||||||
q: map[string]any{
|
|
||||||
"jjj": "ssss",
|
|
||||||
"fff": []int{1, 2, 3},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wantR: res{
|
|
||||||
200, "ok",
|
|
||||||
},
|
|
||||||
wantCode: 200,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
gotR, gotCode, err := GetToJsonAny[res](tt.args.u, tt.args.q, tt.args.a...)
|
|
||||||
if (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("GetToJsonAny() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(gotR, tt.wantR) {
|
|
||||||
t.Errorf("GetToJsonAny() gotR = %v, want %v", gotR, tt.wantR)
|
|
||||||
}
|
|
||||||
if gotCode != tt.wantCode {
|
|
||||||
t.Errorf("GetToJsonAny() gotCode = %v, want %v", gotCode, tt.wantCode)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -27,7 +27,7 @@ func (r anyArr[T]) Less(i, j int) bool {
|
||||||
return r.fn(r.data[i], r.data[j])
|
return r.fn(r.data[i], r.data[j])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort fn i>j 为降序 desc,反之为升序 asc
|
// Sort fn 中i>j 为降序,反之为升序
|
||||||
func Sort[T any](arr []T, fn func(i, j T) bool) {
|
func Sort[T any](arr []T, fn func(i, j T) bool) {
|
||||||
slice := anyArr[T]{
|
slice := anyArr[T]{
|
||||||
data: arr,
|
data: arr,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user