From 09af304a8c056469d5a1b77321c79c75315ad0c6 Mon Sep 17 00:00:00 2001 From: AI Engineer Date: Mon, 8 Jun 2026 21:19:24 +0800 Subject: [PATCH] feat: align JS exports to PascalCase, merge xxxToString, and fix acronyms (by AI) --- encoding.go | 168 ++++++++++++++-------------------------- encoding_test.go | 181 +++++++++++++++++--------------------------- int_encoder.go | 56 ++++++++------ int_encoder_test.go | 88 ++++++++++----------- js_export.go | 46 +++++------ 5 files changed, 221 insertions(+), 318 deletions(-) diff --git a/encoding.go b/encoding.go index 26cb588..b6f34a8 100644 --- a/encoding.go +++ b/encoding.go @@ -12,145 +12,87 @@ import ( "apigo.cc/go/cast" ) -// Hex 将数据转换为 Hex 编码的字节切片 -func Hex(data []byte) []byte { - dst := make([]byte, hex.EncodedLen(len(data))) - hex.Encode(dst, data) - return dst +// Hex 将数据转换为 Hex 编码的字符串 +func Hex(data any) string { + b := cast.To[[]byte](data) + return hex.EncodeToString(b) } -// HexToString 将数据转换为 Hex 编码的字符串 -func HexToString(data []byte) string { - return hex.EncodeToString(data) +// UnHex 将 Hex 编码的数据解码为字节切片 +func UnHex(data any) ([]byte, error) { + s := cast.String(data) + return hex.DecodeString(s) } -// UnHex 将 Hex 编码的字节切片解码 -func UnHex(data []byte) ([]byte, error) { - dst := make([]byte, hex.DecodedLen(len(data))) - n, err := hex.Decode(dst, data) - return dst[:n], err +// Base64 将数据转换为 Base64 编码的字符串 +func Base64(data any) string { + b := cast.To[[]byte](data) + return base64.StdEncoding.EncodeToString(b) } -// UnHexFromString 将 Hex 编码的字符串解码 -func UnHexFromString(data string) ([]byte, error) { - return hex.DecodeString(data) -} - -// Base64 将数据转换为 Base64 编码的字节切片 -func Base64(data []byte) []byte { - buf := make([]byte, base64.StdEncoding.EncodedLen(len(data))) - base64.StdEncoding.Encode(buf, data) - return buf -} - -// Base64ToString 将数据转换为 Base64 编码的字符串 -func Base64ToString(data []byte) string { - return base64.StdEncoding.EncodeToString(data) -} - -// Base64Raw 将数据转换为无填充的 Base64 编码的字节切片 -func Base64Raw(data []byte) []byte { - buf := make([]byte, base64.RawStdEncoding.EncodedLen(len(data))) - base64.RawStdEncoding.Encode(buf, data) - return buf -} - -// Base64RawToString 将数据转换为无填充的 Base64 编码的字符串 -func Base64RawToString(data []byte) string { - return base64.RawStdEncoding.EncodeToString(data) -} - -// UrlBase64 将数据转换为 URL 安全的 Base64 编码的字节切片 -func UrlBase64(data []byte) []byte { - buf := make([]byte, base64.URLEncoding.EncodedLen(len(data))) - base64.URLEncoding.Encode(buf, data) - return buf -} - -// UrlBase64ToString 将数据转换为 URL 安全的 Base64 编码的字符串 -func UrlBase64ToString(data []byte) string { - return base64.URLEncoding.EncodeToString(data) -} - -// UrlBase64Raw 将数据转换为 URL 安全且无填充的 Base64 编码的字节切片 -func UrlBase64Raw(data []byte) []byte { - buf := make([]byte, base64.RawURLEncoding.EncodedLen(len(data))) - base64.RawURLEncoding.Encode(buf, data) - return buf -} - -// UrlBase64RawToString 将数据转换为 URL 安全且无填充的 Base64 编码的字符串 -func UrlBase64RawToString(data []byte) string { - return base64.RawURLEncoding.EncodeToString(data) -} - -// UnBase64 将 Base64 编码的字节切片解码(自动兼容有无填充) -func UnBase64(data []byte) ([]byte, error) { - if len(data) > 0 && data[len(data)-1] == '=' { - dbuf := make([]byte, base64.StdEncoding.DecodedLen(len(data))) - n, err := base64.StdEncoding.Decode(dbuf, data) - return dbuf[:n], err +// UnBase64 将 Base64 编码的数据解码为字节切片(自动兼容有无填充) +func UnBase64(data any) ([]byte, error) { + s := cast.String(data) + if len(s) > 0 && s[len(s)-1] == '=' { + return base64.StdEncoding.DecodeString(s) } - dbuf := make([]byte, base64.RawStdEncoding.DecodedLen(len(data))) - n, err := base64.RawStdEncoding.Decode(dbuf, data) - return dbuf[:n], err + return base64.RawStdEncoding.DecodeString(s) } -// UnBase64FromString 将 Base64 编码的字符串解码(自动兼容有无填充) -func UnBase64FromString(data string) ([]byte, error) { - if len(data) > 0 && data[len(data)-1] == '=' { - return base64.StdEncoding.DecodeString(data) +// Base64Raw 将数据转换为无填充的 Base64 编码的字符串 +func Base64Raw(data any) string { + b := cast.To[[]byte](data) + return base64.RawStdEncoding.EncodeToString(b) +} + +// URLBase64 将数据转换为 URL 安全的 Base64 编码的字符串 +func URLBase64(data any) string { + b := cast.To[[]byte](data) + return base64.URLEncoding.EncodeToString(b) +} + +// UnURLBase64 将 URL 安全的 Base64 编码的数据解码为字节切片(自动兼容有无填充) +func UnURLBase64(data any) ([]byte, error) { + s := cast.String(data) + if len(s) > 0 && s[len(s)-1] == '=' { + return base64.URLEncoding.DecodeString(s) } - return base64.RawStdEncoding.DecodeString(data) + return base64.RawURLEncoding.DecodeString(s) } -// UnUrlBase64 将 URL 安全的 Base64 编码的字节切片解码(自动兼容有无填充) -func UnUrlBase64(data []byte) ([]byte, error) { - if len(data) > 0 && data[len(data)-1] == '=' { - dbuf := make([]byte, base64.URLEncoding.DecodedLen(len(data))) - n, err := base64.URLEncoding.Decode(dbuf, data) - return dbuf[:n], err - } - dbuf := make([]byte, base64.RawURLEncoding.DecodedLen(len(data))) - n, err := base64.RawURLEncoding.Decode(dbuf, data) - return dbuf[:n], err +// URLBase64Raw 将数据转换为 URL 安全且无填充的 Base64 编码的字符串 +func URLBase64Raw(data any) string { + b := cast.To[[]byte](data) + return base64.RawURLEncoding.EncodeToString(b) } -// UnUrlBase64FromString 将 URL 安全的 Base64 编码的字符串解码(自动兼容有无填充) -func UnUrlBase64FromString(data string) ([]byte, error) { - if len(data) > 0 && data[len(data)-1] == '=' { - return base64.URLEncoding.DecodeString(data) - } - return base64.RawURLEncoding.DecodeString(data) +// URLEncode 对数据进行 URL 编码 +func URLEncode(data any) string { + return url.QueryEscape(cast.String(data)) } -// UrlEncode 对数据进行 URL 编码 -func UrlEncode(data []byte) string { - return url.QueryEscape(string(data)) -} - -// UnUrlEncode 对字符串进行 URL 解码 -func UnUrlEncode(data string) ([]byte, error) { - res, err := url.QueryUnescape(data) +// UnURLEncode 对字符串进行 URL 解码 +func UnURLEncode(data any) ([]byte, error) { + res, err := url.QueryUnescape(cast.String(data)) if err != nil { return nil, err } return []byte(res), nil } -// HtmlEscape 对数据进行 HTML 转义 -func HtmlEscape(data []byte) string { - return html.EscapeString(string(data)) +// HTMLEscape 对数据进行 HTML 转义 +func HTMLEscape(data any) string { + return html.EscapeString(cast.String(data)) } -// HtmlUnescape 对 HTML 字符串进行反转义 -func HtmlUnescape(data string) string { - return html.UnescapeString(data) +// HTMLUnescape 对 HTML 字符串进行反转义 +func HTMLUnescape(data any) string { + return html.UnescapeString(cast.String(data)) } -// Utf8Valid 检查字节切片是否为有效的 UTF-8 编码 -func Utf8Valid(data []byte) bool { - return utf8.Valid(data) +// UTF8Valid 检查数据是否为有效的 UTF-8 编码 +func UTF8Valid(data any) bool { + return utf8.Valid(cast.To[[]byte](data)) } // SortJoin 将 Map 或 Struct 转换为排序并拼接后的字符串 (常用于签名) diff --git a/encoding_test.go b/encoding_test.go index c581948..98c0c53 100644 --- a/encoding_test.go +++ b/encoding_test.go @@ -1,135 +1,96 @@ -package encoding_test +package encoding import ( "bytes" "testing" - - "apigo.cc/go/cast" - "apigo.cc/go/encoding" ) -// --- Hex --- -func TestHex(t *testing.T) { - data := []byte("hello go") - encoded := encoding.HexToString(data) - decoded, err := encoding.UnHex([]byte(encoded)) - if err != nil || !bytes.Equal(data, decoded) { - t.Fatal("Hex roundtrip failed") - } - - if !bytes.Equal(cast.As(encoding.UnHexFromString(encoded)), data) { - t.Error("UnHexFromString with cast.As failed") - } - - if len(cast.As(encoding.UnHexFromString("!@#$"))) != 0 { - t.Error("UnHexFromString should return empty for invalid hex chars with cast.As") - } -} - -// --- Base64 --- -func TestBase64(t *testing.T) { +func TestEncoding(t *testing.T) { data := []byte("hello world") - - // Standard - enc := encoding.Base64ToString(data) - dec, err := encoding.UnBase64([]byte(enc)) - if err != nil || !bytes.Equal(data, dec) { - t.Error("Base64 roundtrip failed") - } - - if !bytes.Equal(cast.As(encoding.UnBase64FromString(enc)), data) { - t.Error("UnBase64FromString with cast.As failed") + + // Hex + encoded := Hex(data) + decoded, err := UnHex(encoded) + if err != nil || !bytes.Equal(decoded, data) { + t.Errorf("Hex failed: got %v, error: %v", decoded, err) } - // Raw (Unpadded) - rawEnc := encoding.Base64RawToString(data) - if bytes.HasSuffix([]byte(rawEnc), []byte("=")) { - t.Error("Base64Raw should not have padding") - } - rawDec, err := encoding.UnBase64FromString(rawEnc) - if err != nil || !bytes.Equal(data, rawDec) { - t.Error("Base64Raw smart decoding failed") - } - - // URL - uData := []byte("hello/world+") - uEnc := encoding.UrlBase64ToString(uData) - uDec, _ := encoding.UnUrlBase64([]byte(uEnc)) - if !bytes.Equal(uData, uDec) { - t.Error("UrlBase64 roundtrip failed") + // Base64 + enc := Base64(data) + dec, err := UnBase64(enc) + if err != nil || !bytes.Equal(dec, data) { + t.Errorf("Base64 failed: got %v, error: %v", dec, err) } - if !bytes.Equal(cast.As(encoding.UnUrlBase64FromString(uEnc)), uData) { - t.Error("UnUrlBase64FromString with cast.As failed") + // Base64Raw + rawEnc := Base64Raw(data) + rawDec, err := UnBase64(rawEnc) + if err != nil || !bytes.Equal(rawDec, data) { + t.Errorf("Base64Raw failed: got %v, error: %v", rawDec, err) } - // URL Raw (Unpadded) - uRawEnc := encoding.UrlBase64RawToString(uData) - if bytes.HasSuffix([]byte(uRawEnc), []byte("=")) { - t.Error("UrlBase64Raw should not have padding") + // URLBase64 + uData := []byte("https://apigo.cc?a=1&b=2") + uEnc := URLBase64(uData) + uDec, _ := UnURLBase64(uEnc) + if !bytes.Equal(uDec, uData) { + t.Errorf("URLBase64 failed: got %v", uDec) } - uRawDec, err := encoding.UnUrlBase64FromString(uRawEnc) - if err != nil || !bytes.Equal(uData, uRawDec) { - t.Error("UrlBase64Raw smart decoding failed") + + // URLBase64Raw + uRawEnc := URLBase64Raw(uData) + uRawDec, err := UnURLBase64(uRawEnc) + if err != nil || !bytes.Equal(uRawDec, uData) { + t.Errorf("URLBase64Raw failed: got %v, error: %v", uRawDec, err) + } + + // URLEncode + urlEnc := URLEncode(data) + urlDec, err := UnURLEncode(urlEnc) + if err != nil || !bytes.Equal(urlDec, data) { + t.Errorf("URLEncode failed: got %v, error: %v", urlDec, err) + } + + // HTMLEscape + htmlData := "
hello
" + escaped := HTMLEscape(htmlData) + if HTMLUnescape(escaped) != htmlData { + t.Errorf("HTMLEscape failed") + } + + // UTF8Valid + if !UTF8Valid("你好") { + t.Error("UTF8Valid failed") } } -// --- Web --- -func TestWebEncoding(t *testing.T) { - // URL - data := []byte("a b+c") - enc := encoding.UrlEncode(data) - if !bytes.Equal(cast.As(encoding.UnUrlEncode(enc)), data) { - t.Error("UrlEncode roundtrip failed") - } - if len(cast.As(encoding.UnUrlEncode("%ZZ"))) != 0 { - t.Error("UnUrlEncode should return empty for invalid input with cast.As") - } - - // HTML - htmlData := []byte("