From 082790b995b010715d67a212a30d6721817e2dae Mon Sep 17 00:00:00 2001 From: tomholford Date: Tue, 30 Jul 2024 22:01:46 -0700 Subject: [PATCH 1/4] co: helpers + generic interface - also added test helpers + coverage --- co/co.go | 85 +++++++- co/co_test.go | 494 ++++++++++++++++++++++++++++++++++++++++++--- internal/errors.go | 1 + 3 files changed, 542 insertions(+), 38 deletions(-) diff --git a/co/co.go b/co/co.go index 32a9f9b..fad6c0e 100644 --- a/co/co.go +++ b/co/co.go @@ -199,10 +199,25 @@ func patp2bn(name string) (*big.Int, error) { return hex, nil } +// Patp2Point converts a @p-encoded string to a big.Int pointer. +func Patp2Point(name string) (*big.Int, error) { + int, err := patp2bn(name) + if err != nil { + return nil, err + } + + return int, nil +} + +// Point2Patp converts a big.Int pointer to a @p-encoded string. +func Point2Patp(int *big.Int) (string, error) { + return Patp(int.String()) +} + // Patp2Dec converts a @p-encoded string to a decimal-encoded string. func Patp2Dec(name string) (string, error) { - dec, err := patp2bn(name) + dec, err := Patp2Point(name) if err != nil { return "", err } @@ -211,7 +226,7 @@ func Patp2Dec(name string) (string, error) { } // Patq converts a number to a @q-encoded string. -func Patq(arg string) (string, error) { +func patq(arg string) (string, error) { v, ok := big.NewInt(0).SetString(arg, 10) if !ok { @@ -226,6 +241,33 @@ func Patq(arg string) (string, error) { return buf2patq(buf), nil } +// Patq2Dec converts a string-encoded int or *big.Int to a @q-encoded string. +func Patq(arg interface{}) (string, error) { + switch v := arg.(type) { + case string: + return patq(v) + case *big.Int: + return patq(v.String()) + default: + return "", fmt.Errorf(ugi.ErrInvalidQ, v) + } +} + +// Patq2Point converts a @q-encoded string to a big.Int pointer. +func Patq2Point(name string) (*big.Int, error) { + int, err := patq2bn(name) + if err != nil { + return nil, err + } + + return int, nil +} + +// Point2Patq converts a big.Int pointer to a @q-encoded string. +func Point2Patq(int *big.Int) (string, error) { + return Patq(int.String()) +} + func buf2patq(buf []byte) string { var chunked [][]byte @@ -409,6 +451,15 @@ func Clan(who string) (string, error) { return ShipClassComet, nil } +// ClanPoint determines the ship class of a big.Int-encoded @p value. +func ClanPoint(arg *big.Int) (string, error) { + patp, err := Patp(arg) + if err != nil { + return "", err + } + return Clan(patp) +} + // Sein determines the parent of a @p value. func Sein(name string) (string, error) { @@ -439,6 +490,20 @@ func Sein(name string) (string, error) { return Patp(res.String()) } +// SeinPoint determines the parent of a big.Int-encoded @p value. +func SeinPoint(arg *big.Int) (*big.Int, error) { + patp, err := Point2Patp(arg) + if err != nil { + return nil, err + } + sein, err := Sein(patp) + if err != nil { + return nil, err + } + + return Patp2Point(sein) +} + /* IsValidPat weakly checks if a string is a valid @p or @q value. @@ -539,9 +604,7 @@ func EqPatq(p, q string) (bool, error) { return eqModLeadingZeros(phex, qhex), nil } -// Patp converts a number to a @p-encoded string. -func Patp(arg string) (string, error) { - +func patp(arg string) (string, error) { v, ok := big.NewInt(0).SetString(arg, 10) if !ok { return "", fmt.Errorf(ugi.ErrInvalidInt, arg) @@ -566,6 +629,18 @@ func Patp(arg string) (string, error) { return p, nil } +// Patp converts a either a string-encoded int or *big.Int to a @p-encoded string. +func Patp(arg interface{}) (string, error) { + switch v := arg.(type) { + case string: + return patp(v) + case *big.Int: + return patp(v.String()) + default: + return "", fmt.Errorf(ugi.ErrInvalidP, arg) + } +} + func patpLoop(dyy, tsxz, timp *big.Int, trep string) string { log := end(four, one, tsxz) diff --git a/co/co_test.go b/co/co_test.go index ccad064..62171c7 100644 --- a/co/co_test.go +++ b/co/co_test.go @@ -1,21 +1,56 @@ package co import ( + "math/big" "testing" "github.com/stretchr/testify/assert" ) -type stdTestCase struct { +// test helpers +// s2s: string to string +// s2i: string to integer - TODO: is this needed? +// i2s: integer to string +// i2i: integer to integer +// a2s: any type to string + +type s2sTestCase struct { + in string + out string + expectedErrText string +} + +type s2iTestCase struct { in string + out *big.Int + expectedErrText string +} + +type i2sTestCase struct { + in *big.Int out string expectedErrText string } -type stdCoFn func(string) (string, error) +type i2iTestCase struct { + in *big.Int + out *big.Int + expectedErrText string +} + +type a2sTestCase struct { + in interface{} + out string + expectedErrText string +} -func stdTestRunner(t *testing.T, testCases []stdTestCase, f stdCoFn) { +type s2sCoFn func(string) (string, error) +type s2iCoFn func(string) (*big.Int, error) +type i2sCoFn func(*big.Int) (string, error) +type i2iCoFn func(*big.Int) (*big.Int, error) +type a2sCoFn func(interface{}) (string, error) +func s2sTestRunner(t *testing.T, testCases []s2sTestCase, f s2sCoFn) { for _, tt := range testCases { t.Run(tt.in, func(t *testing.T) { @@ -34,9 +69,86 @@ func stdTestRunner(t *testing.T, testCases []stdTestCase, f stdCoFn) { } } -func TestPatp(t *testing.T) { +func s2iTestRunner(t *testing.T, testCases []s2iTestCase, f s2iCoFn) { + for _, tt := range testCases { + t.Run(tt.in, func(t *testing.T) { + + actualOut, actualErr := f(tt.in) - var testCases = []stdTestCase{ + assert.Equal(t, tt.out, actualOut) + if tt.expectedErrText == "" { + assert.NoError(t, actualErr) + } else { + assert.Error(t, actualErr) + if actualErr != nil { + assert.Equal(t, tt.expectedErrText, actualErr.Error()) + } + } + }) + } +} + +func i2sTestRunner(t *testing.T, testCases []i2sTestCase, f i2sCoFn) { + for _, tt := range testCases { + t.Run(tt.in.String(), func(t *testing.T) { + + actualOut, actualErr := f(tt.in) + + assert.Equal(t, tt.out, actualOut) + if tt.expectedErrText == "" { + assert.NoError(t, actualErr) + } else { + assert.Error(t, actualErr) + if actualErr != nil { + assert.Equal(t, tt.expectedErrText, actualErr.Error()) + } + } + }) + } +} + +func i2iTestRunner(t *testing.T, testCases []i2iTestCase, f i2iCoFn) { + for _, tt := range testCases { + t.Run(tt.in.String(), func(t *testing.T) { + + actualOut, actualErr := f(tt.in) + + assert.Equal(t, tt.out, actualOut) + if tt.expectedErrText == "" { + assert.NoError(t, actualErr) + } else { + assert.Error(t, actualErr) + if actualErr != nil { + assert.Equal(t, tt.expectedErrText, actualErr.Error()) + } + } + }) + } +} + +func a2sTestRunner(t *testing.T, testCases []a2sTestCase, f a2sCoFn) { + for _, tt := range testCases { + t.Run(tt.in.(string), func(t *testing.T) { + + actualOut, actualErr := f(tt.in) + + assert.Equal(t, tt.out, actualOut) + if tt.expectedErrText == "" { + assert.NoError(t, actualErr) + } else { + assert.Error(t, actualErr) + if actualErr != nil { + assert.Equal(t, tt.expectedErrText, actualErr.Error()) + } + } + }) + } +} + +// --- tests --- + +func TestPatp(t *testing.T) { + var testCases = []a2sTestCase{ { in: "0", out: "~zod", @@ -87,12 +199,11 @@ func TestPatp(t *testing.T) { }, } - stdTestRunner(t, testCases, Patp) + a2sTestRunner(t, testCases, Patp) } func TestPatq(t *testing.T) { - - var testCases = []stdTestCase{ + var testCases = []a2sTestCase{ { in: "0", out: "~zod", @@ -143,12 +254,11 @@ func TestPatq(t *testing.T) { }, } - stdTestRunner(t, testCases, Patq) + a2sTestRunner(t, testCases, Patq) } func TestClan(t *testing.T) { - - var testCases = []stdTestCase{ + var testCases = []s2sTestCase{ { in: "~zod", out: ShipClassGalaxy, @@ -203,12 +313,11 @@ func TestClan(t *testing.T) { }, } - stdTestRunner(t, testCases, Clan) + s2sTestRunner(t, testCases, Clan) } func TestSein(t *testing.T) { - - var testCases = []stdTestCase{ + var testCases = []s2sTestCase{ { in: "~zod", out: "~zod", @@ -263,12 +372,11 @@ func TestSein(t *testing.T) { }, } - stdTestRunner(t, testCases, Sein) + s2sTestRunner(t, testCases, Sein) } func TestPatp2Dec(t *testing.T) { - - var testCases = []stdTestCase{ + var testCases = []s2sTestCase{ { out: "0", in: "~zod", @@ -319,12 +427,11 @@ func TestPatp2Dec(t *testing.T) { }, } - stdTestRunner(t, testCases, Patp2Dec) + s2sTestRunner(t, testCases, Patp2Dec) } func TestPatq2Dec(t *testing.T) { - - var testCases = []stdTestCase{ + var testCases = []s2sTestCase{ { out: "0", in: "~zod", @@ -375,12 +482,11 @@ func TestPatq2Dec(t *testing.T) { }, } - stdTestRunner(t, testCases, Patq2Dec) + s2sTestRunner(t, testCases, Patq2Dec) } func TestPatp2Hex(t *testing.T) { - - var testCases = []stdTestCase{ + var testCases = []s2sTestCase{ { out: "00", in: "~zod", @@ -431,12 +537,11 @@ func TestPatp2Hex(t *testing.T) { }, } - stdTestRunner(t, testCases, Patp2Hex) + s2sTestRunner(t, testCases, Patp2Hex) } func TestPatq2Hex(t *testing.T) { - - var testCases = []stdTestCase{ + var testCases = []s2sTestCase{ { out: "00", in: "~zod", @@ -488,12 +593,11 @@ func TestPatq2Hex(t *testing.T) { }, } - stdTestRunner(t, testCases, Patq2Hex) + s2sTestRunner(t, testCases, Patq2Hex) } func TestHex2Patp(t *testing.T) { - - var testCases = []stdTestCase{ + var testCases = []s2sTestCase{ { in: "00", out: "~zod", @@ -544,12 +648,11 @@ func TestHex2Patp(t *testing.T) { }, } - stdTestRunner(t, testCases, Hex2Patp) + s2sTestRunner(t, testCases, Hex2Patp) } func TestHex2Patq(t *testing.T) { - - var testCases = []stdTestCase{ + var testCases = []s2sTestCase{ { in: "00", out: "~zod", @@ -600,5 +703,330 @@ func TestHex2Patq(t *testing.T) { }, } - stdTestRunner(t, testCases, Hex2Patq) + s2sTestRunner(t, testCases, Hex2Patq) +} + +func TestPatp2Point(t *testing.T) { + var testCases = []s2iTestCase{ + { + in: "~zod", + out: big.NewInt(0), + }, + { + in: "~fes", + out: big.NewInt(255), + }, + { + in: "~marzod", + out: big.NewInt(256), + }, + { + in: "~fipfes", + out: big.NewInt(65535), + }, + { + in: "~dapnep-ronmyl", + out: big.NewInt(65536), + }, + { + in: "~rosmur-hobrem", + out: big.NewInt(14287616), + }, + { + in: "~sallus-nodlut", + out: big.NewInt(14287617), + }, + { + in: "~marder-mopdur", + out: big.NewInt(14287618), + }, + { + in: "~laphec-savted", + out: big.NewInt(14287619), + }, + { + in: "~dostec-risfen", + out: big.NewInt(4294967295), + }, + { + in: "~doznec-dozzod-dozzod", + out: big.NewInt(4294967296), + }, + { + in: "~abcdefg", + expectedErrText: "invalid @p: ~abcdefg", + }, + } + + s2iTestRunner(t, testCases, Patp2Point) } + +// Point2Patp +func TestPoint2Patp(t *testing.T) { + var testCases = []i2sTestCase{ + { + in: big.NewInt(0), + out: "~zod", + }, + { + in: big.NewInt(255), + out: "~fes", + }, + { + in: big.NewInt(256), + out: "~marzod", + }, + { + in: big.NewInt(65535), + out: "~fipfes", + }, + { + in: big.NewInt(65536), + out: "~dapnep-ronmyl", + }, + { + in: big.NewInt(14287616), + out: "~rosmur-hobrem", + }, + { + in: big.NewInt(14287617), + out: "~sallus-nodlut", + }, + { + in: big.NewInt(14287618), + out: "~marder-mopdur", + }, + { + in: big.NewInt(14287619), + out: "~laphec-savted", + }, + { + in: big.NewInt(4294967295), + out: "~dostec-risfen", + }, + { + in: big.NewInt(4294967296), + out: "~doznec-dozzod-dozzod", + }, + } + + i2sTestRunner(t, testCases, Point2Patp) +} + +// Patq2Point +func TestPatq2Point(t *testing.T) { + var testCases = []s2iTestCase{ + { + in: "~zod", + out: big.NewInt(0), + }, + { + in: "~fes", + out: big.NewInt(255), + }, + { + in: "~marzod", + out: big.NewInt(256), + }, + { + in: "~fipfes", + out: big.NewInt(65535), + }, + { + in: "~doznec-dozzod", + out: big.NewInt(65536), + }, + { + in: "~dozler-wanzod", + out: big.NewInt(14287616), + }, + { + in: "~dozler-wannec", + out: big.NewInt(14287617), + }, + { + in: "~dozler-wanbud", + out: big.NewInt(14287618), + }, + { + in: "~dozler-wanwes", + out: big.NewInt(14287619), + }, + { + in: "~fipfes-fipfes", + out: big.NewInt(4294967295), + }, + { + in: "~doznec-dozzod-dozzod", + out: big.NewInt(4294967296), + }, + { + in: "abcdefg", + expectedErrText: "invalid @q: abcdefg", + }, + } + + s2iTestRunner(t, testCases, Patq2Point) +} + +// Point2Patq +func TestPoint2Patq(t *testing.T) { + var testCases = []i2sTestCase{ + { + in: big.NewInt(0), + out: "~zod", + }, + { + in: big.NewInt(255), + out: "~fes", + }, + { + in: big.NewInt(256), + out: "~marzod", + }, + { + in: big.NewInt(65535), + out: "~fipfes", + }, + { + in: big.NewInt(65536), + out: "~doznec-dozzod", + }, + { + in: big.NewInt(14287616), + out: "~dozler-wanzod", + }, + { + in: big.NewInt(14287617), + out: "~dozler-wannec", + }, + { + in: big.NewInt(14287618), + out: "~dozler-wanbud", + }, + { + in: big.NewInt(14287619), + out: "~dozler-wanwes", + }, + { + in: big.NewInt(4294967295), + out: "~fipfes-fipfes", + }, + { + in: big.NewInt(4294967296), + out: "~doznec-dozzod-dozzod", + }, + } + + i2sTestRunner(t, testCases, Point2Patq) +} + +// SeinPoint +func TestSeinPoint(t *testing.T) { + var testCases = []i2iTestCase{ + { + in: big.NewInt(0), + out: big.NewInt(0), + }, + { + in: big.NewInt(255), + out: big.NewInt(255), + }, + { + in: big.NewInt(256), + out: big.NewInt(0), + }, + { + in: big.NewInt(65535), + out: big.NewInt(255), + }, + { + in: big.NewInt(65536), + out: big.NewInt(0), + }, + { + in: big.NewInt(14287616), + out: big.NewInt(768), + }, + { + in: big.NewInt(14287617), + out: big.NewInt(769), + }, + { + in: big.NewInt(14287618), + out: big.NewInt(770), + }, + { + in: big.NewInt(14287619), + out: big.NewInt(771), + }, + { + in: big.NewInt(4294967295), + out: big.NewInt(65535), + }, + { + in: big.NewInt(4294967296), + out: big.NewInt(0), + }, + } + + i2iTestRunner(t, testCases, SeinPoint) +} + +// ClanPoint +func TestClanPoint(t *testing.T) { + var testCases = []i2sTestCase{ + { + in: big.NewInt(0), + out: ShipClassGalaxy, + }, + { + in: big.NewInt(255), + out: ShipClassGalaxy, + }, + { + in: big.NewInt(256), + out: ShipClassStar, + }, + { + in: big.NewInt(65535), + out: ShipClassStar, + }, + { + in: big.NewInt(65536), + out: ShipClassPlanet, + }, + { + in: big.NewInt(14287616), + out: ShipClassPlanet, + }, + { + in: big.NewInt(14287617), + out: ShipClassPlanet, + }, + { + in: big.NewInt(14287618), + out: ShipClassPlanet, + }, + { + in: big.NewInt(14287619), + out: ShipClassPlanet, + }, + { + in: big.NewInt(4294967295), + out: ShipClassPlanet, + }, + { + in: big.NewInt(4294967296), + out: ShipClassMoon, + }, + } + + i2sTestRunner(t, testCases, ClanPoint) +} + +// TODO: +// +// Patp can handle string or int +// Patq can handle string or int +// string prepended / not with ~ diff --git a/internal/errors.go b/internal/errors.go index 77f42d3..fcb9c25 100644 --- a/internal/errors.go +++ b/internal/errors.go @@ -7,4 +7,5 @@ const ( ErrInvalidInt string = "invalid integer string: %s" ErrInvalidP string = "invalid @p: %s" ErrInvalidQ string = "invalid @q: %s" + ErrInvalidI string = "invalid integer: %s" ) From 9dd2e89e36db5274a932ab340191f184753a78e7 Mon Sep 17 00:00:00 2001 From: tomholford Date: Wed, 31 Jul 2024 02:07:16 -0700 Subject: [PATCH 2/4] co: more tests for patp / patq --- co/co_test.go | 101 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 3 deletions(-) diff --git a/co/co_test.go b/co/co_test.go index 62171c7..3ff8a4c 100644 --- a/co/co_test.go +++ b/co/co_test.go @@ -128,8 +128,17 @@ func i2iTestRunner(t *testing.T, testCases []i2iTestCase, f i2iCoFn) { func a2sTestRunner(t *testing.T, testCases []a2sTestCase, f a2sCoFn) { for _, tt := range testCases { - t.Run(tt.in.(string), func(t *testing.T) { + var testName string + switch v := tt.in.(type) { + case string: + testName = v + case *big.Int: + testName = v.String() + default: + testName = "unknown" + } + t.Run(testName, func(t *testing.T) { actualOut, actualErr := f(tt.in) assert.Equal(t, tt.out, actualOut) @@ -193,6 +202,50 @@ func TestPatp(t *testing.T) { in: "4294967296", out: "~doznec-dozzod-dozzod", }, + { + in: big.NewInt(0), + out: "~zod", + }, + { + in: big.NewInt(255), + out: "~fes", + }, + { + in: big.NewInt(256), + out: "~marzod", + }, + { + in: big.NewInt(65535), + out: "~fipfes", + }, + { + in: big.NewInt(65536), + out: "~dapnep-ronmyl", + }, + { + in: big.NewInt(14287616), + out: "~rosmur-hobrem", + }, + { + in: big.NewInt(14287617), + out: "~sallus-nodlut", + }, + { + in: big.NewInt(14287618), + out: "~marder-mopdur", + }, + { + in: big.NewInt(14287619), + out: "~laphec-savted", + }, + { + in: big.NewInt(4294967295), + out: "~dostec-risfen", + }, + { + in: big.NewInt(4294967296), + out: "~doznec-dozzod-dozzod", + }, { in: "abcdefg", expectedErrText: "invalid integer string: abcdefg", @@ -248,6 +301,50 @@ func TestPatq(t *testing.T) { in: "4294967296", out: "~doznec-dozzod-dozzod", }, + { + in: big.NewInt(0), + out: "~zod", + }, + { + in: big.NewInt(255), + out: "~fes", + }, + { + in: big.NewInt(256), + out: "~marzod", + }, + { + in: big.NewInt(65535), + out: "~fipfes", + }, + { + in: big.NewInt(65536), + out: "~doznec-dozzod", + }, + { + in: big.NewInt(14287616), + out: "~dozler-wanzod", + }, + { + in: big.NewInt(14287617), + out: "~dozler-wannec", + }, + { + in: big.NewInt(14287618), + out: "~dozler-wanbud", + }, + { + in: big.NewInt(14287619), + out: "~dozler-wanwes", + }, + { + in: big.NewInt(4294967295), + out: "~fipfes-fipfes", + }, + { + in: big.NewInt(4294967296), + out: "~doznec-dozzod-dozzod", + }, { in: "abcdefg", expectedErrText: "invalid integer string: abcdefg", @@ -1027,6 +1124,4 @@ func TestClanPoint(t *testing.T) { // TODO: // -// Patp can handle string or int -// Patq can handle string or int // string prepended / not with ~ From fbc67fae2b89d7e750bf17caa97380911b850e81 Mon Sep 17 00:00:00 2001 From: tomholford Date: Wed, 31 Jul 2024 02:22:10 -0700 Subject: [PATCH 3/4] cmd: cli supports new fns also, update readme --- cmd/main.go | 65 +++++++++++++++++++++++++++++++++++++++++++++-------- readme.md | 12 ++++++++++ 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index b1d1267..2321265 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -3,27 +3,36 @@ package main import ( "flag" "fmt" + "math/big" "os" + "strconv" "github.com/deelawn/urbit-gob/co" ) const ( // Commands - cmdPatp string = "patp" - cmdPatp2Dec string = "patp2dec" - cmdPatp2Hex string = "patp2hex" + cmdPatp string = "patp" + cmdPatp2Dec string = "patp2dec" + cmdPatp2Hex string = "patp2hex" + cmdPatp2Point string = "patp2point" - cmdPatq string = "patq" - cmdPatq2Dec string = "patq2dec" - cmdPatq2Hex string = "patq2hex" + cmdPatq string = "patq" + cmdPatq2Dec string = "patq2dec" + cmdPatq2Hex string = "patq2hex" + cmdPatq2Point string = "patq2point" + + cmdPoint2Patp string = "point2patp" + cmdPoint2Patq string = "point2patq" cmdHex2Patp string = "hex2patp" cmdHex2Patq string = "hex2patq" - cmdClan string = "clan" - cmdSein string = "sein" - cmdEqPatq string = "eqpatq" + cmdClan string = "clan" + cmdClanPoint string = "clanpoint" + cmdSein string = "sein" + cmdSeinPoint string = "seinpoint" + cmdEqPatq string = "eqpatq" cmdIsValidPat string = "isvalidpat" cmdIsValidPatp string = "isvalidpatp" @@ -49,13 +58,19 @@ func main() { fmt.Printf(usageCmdFmtStr, cmdPatp, "converts a number to a @p-encoded string\n") fmt.Printf(usageCmdFmtStr, cmdPatp2Dec, "converts a @p-encoded string to a decimal-encoded string\n") fmt.Printf(usageCmdFmtStr, cmdPatp2Hex, "converts a @p-encoded string to a hex-encoded string\n") + fmt.Printf(usageCmdFmtStr, cmdPatp2Point, "converts a @p-encoded string to a big.Int\n") fmt.Printf(usageCmdFmtStr, cmdPatq, "converts a number to a @q-encoded string\n") fmt.Printf(usageCmdFmtStr, cmdPatq2Dec, "converts a @q-encoded string to a decimal-encoded string\n") fmt.Printf(usageCmdFmtStr, cmdPatq2Hex, "converts a @q-encoded string to a hex-encoded string\n") + fmt.Printf(usageCmdFmtStr, cmdPatq2Point, "converts a @q-encoded string to a big.Int\n") + fmt.Printf(usageCmdFmtStr, cmdPoint2Patp, "converts a big.Int to a @p-encoded string\n") + fmt.Printf(usageCmdFmtStr, cmdPoint2Patq, "converts a big.Int to a @q-encoded string\n") fmt.Printf(usageCmdFmtStr, cmdHex2Patp, "converts a hex-encoded string to a @p-encoded string\n") fmt.Printf(usageCmdFmtStr, cmdHex2Patq, "converts a hex-encoded string to a @q-encoded string\n") fmt.Printf(usageCmdFmtStr, cmdClan, "determines the ship class of a @p value\n") + fmt.Printf(usageCmdFmtStr, cmdClanPoint, "determines the ship class of a big.Int\n") fmt.Printf(usageCmdFmtStr, cmdSein, "determines the parent of a @p value\n") + fmt.Printf(usageCmdFmtStr, cmdSeinPoint, "determines the parent of a big.Int\n") fmt.Printf(usageCmdFmtStr, cmdEqPatq, "performs an equality comparison on @q values\n") fmt.Printf(usageCmdFmtStr, cmdIsValidPat, "weakly checks if a string is a valid @p or @q value\n") fmt.Printf(usageCmdFmtStr, cmdIsValidPatp, "validates a @p string\n") @@ -83,20 +98,52 @@ func main() { result, err = co.Patp2Dec(args[1]) case cmdPatp2Hex: result, err = co.Patp2Hex(args[1]) + case cmdPatp2Point: + result, err = co.Patp2Point(args[1]) case cmdPatq: result, err = co.Patq(args[1]) case cmdPatq2Dec: result, err = co.Patq2Dec(args[1]) case cmdPatq2Hex: result, err = co.Patq2Hex(args[1]) + case cmdPatq2Point: + result, err = co.Patq2Point(args[1]) + case cmdPoint2Patp: + i, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + fmt.Println(err) + os.Exit(codeErrorReturned) + } + result, err = co.Point2Patp(big.NewInt(i)) + case cmdPoint2Patq: + i, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + fmt.Println(err) + os.Exit(codeErrorReturned) + } + result, err = co.Point2Patq(big.NewInt(i)) case cmdHex2Patp: result, err = co.Hex2Patp(args[1]) case cmdHex2Patq: result, err = co.Hex2Patq(args[1]) case cmdClan: result, err = co.Clan(args[1]) + case cmdClanPoint: + i, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + fmt.Println(err) + os.Exit(codeErrorReturned) + } + result, err = co.ClanPoint(big.NewInt(i)) case cmdSein: result, err = co.Sein(args[1]) + case cmdSeinPoint: + i, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + fmt.Println(err) + os.Exit(codeErrorReturned) + } + result, err = co.SeinPoint(big.NewInt(i)) case cmdIsValidPat: result = co.IsValidPat(args[1]) case cmdIsValidPatp: diff --git a/readme.md b/readme.md index df3eceb..bdd8b3d 100644 --- a/readme.md +++ b/readme.md @@ -23,20 +23,32 @@ Valid commands: patp2hex : converts a @p-encoded string to a hex-encoded string + patp2point : converts a @p-encoded string to a point-encoded string + patq : converts a number to a @q-encoded string patq2dec : converts a @q-encoded string to a decimal-encoded string patq2hex : converts a @q-encoded string to a hex-encoded string + patq2point : converts a @q-encoded string to a point-encoded string + + point2patp : converts a point-encoded string to a @p-encoded string + + point2patq : converts a point-encoded string to a @q-encoded string + hex2patp : converts a hex-encoded string to a @p-encoded string hex2patq : converts a hex-encoded string to a @q-encoded string clan : determines the ship class of a @p value + clanpoint : determines the ship class of an int-encoded point + sein : determines the parent of a @p value + seinpoint : determines the parent of an int-encoded point + eqpatq : performs an equality comparison on @q values isvalidpat : weakly checks if a string is a valid @p or @q value From 1ab41b05c3b9845c9e905e2e8a664bbd5bf0376d Mon Sep 17 00:00:00 2001 From: tomholford Date: Wed, 31 Jul 2024 07:02:17 -0700 Subject: [PATCH 4/4] co: names, style, feedback --- co/co.go | 19 +++++---- co/co_test.go | 104 +++++++++++++++++++++++++------------------------- 2 files changed, 61 insertions(+), 62 deletions(-) diff --git a/co/co.go b/co/co.go index fad6c0e..a101b72 100644 --- a/co/co.go +++ b/co/co.go @@ -201,17 +201,17 @@ func patp2bn(name string) (*big.Int, error) { // Patp2Point converts a @p-encoded string to a big.Int pointer. func Patp2Point(name string) (*big.Int, error) { - int, err := patp2bn(name) + point, err := patp2bn(name) if err != nil { return nil, err } - return int, nil + return point, nil } // Point2Patp converts a big.Int pointer to a @p-encoded string. -func Point2Patp(int *big.Int) (string, error) { - return Patp(int.String()) +func Point2Patp(point *big.Int) (string, error) { + return Patp(point.String()) } // Patp2Dec converts a @p-encoded string to a decimal-encoded string. @@ -225,7 +225,6 @@ func Patp2Dec(name string) (string, error) { return dec.String(), nil } -// Patq converts a number to a @q-encoded string. func patq(arg string) (string, error) { v, ok := big.NewInt(0).SetString(arg, 10) @@ -241,7 +240,7 @@ func patq(arg string) (string, error) { return buf2patq(buf), nil } -// Patq2Dec converts a string-encoded int or *big.Int to a @q-encoded string. +// Patq converts a string-encoded int or *big.Int to a @q-encoded string. func Patq(arg interface{}) (string, error) { switch v := arg.(type) { case string: @@ -255,17 +254,17 @@ func Patq(arg interface{}) (string, error) { // Patq2Point converts a @q-encoded string to a big.Int pointer. func Patq2Point(name string) (*big.Int, error) { - int, err := patq2bn(name) + point, err := patq2bn(name) if err != nil { return nil, err } - return int, nil + return point, nil } // Point2Patq converts a big.Int pointer to a @q-encoded string. -func Point2Patq(int *big.Int) (string, error) { - return Patq(int.String()) +func Point2Patq(point *big.Int) (string, error) { + return Patq(point.String()) } func buf2patq(buf []byte) string { diff --git a/co/co_test.go b/co/co_test.go index 3ff8a4c..f70fc82 100644 --- a/co/co_test.go +++ b/co/co_test.go @@ -8,49 +8,49 @@ import ( ) // test helpers -// s2s: string to string -// s2i: string to integer - TODO: is this needed? -// i2s: integer to string -// i2i: integer to integer -// a2s: any type to string +// string2String: string to string +// string2Int: string to integer - TODO: is this needed? +// int2String: integer to string +// int2Int: integer to integer +// any2String: any type to string -type s2sTestCase struct { +type string2StringTestCase struct { in string out string expectedErrText string } -type s2iTestCase struct { +type string2IntTestCase struct { in string out *big.Int expectedErrText string } -type i2sTestCase struct { +type int2StringTestCase struct { in *big.Int out string expectedErrText string } -type i2iTestCase struct { +type int2IntTestCase struct { in *big.Int out *big.Int expectedErrText string } -type a2sTestCase struct { +type any2StringTestCase struct { in interface{} out string expectedErrText string } -type s2sCoFn func(string) (string, error) -type s2iCoFn func(string) (*big.Int, error) -type i2sCoFn func(*big.Int) (string, error) -type i2iCoFn func(*big.Int) (*big.Int, error) -type a2sCoFn func(interface{}) (string, error) +type string2StringCoFn func(string) (string, error) +type string2IntCoFn func(string) (*big.Int, error) +type int2StringCoFn func(*big.Int) (string, error) +type int2IntCoFn func(*big.Int) (*big.Int, error) +type any2StringCoFn func(interface{}) (string, error) -func s2sTestRunner(t *testing.T, testCases []s2sTestCase, f s2sCoFn) { +func string2StringTestRunner(t *testing.T, testCases []string2StringTestCase, f string2StringCoFn) { for _, tt := range testCases { t.Run(tt.in, func(t *testing.T) { @@ -69,7 +69,7 @@ func s2sTestRunner(t *testing.T, testCases []s2sTestCase, f s2sCoFn) { } } -func s2iTestRunner(t *testing.T, testCases []s2iTestCase, f s2iCoFn) { +func string2IntTestRunner(t *testing.T, testCases []string2IntTestCase, f string2IntCoFn) { for _, tt := range testCases { t.Run(tt.in, func(t *testing.T) { @@ -88,7 +88,7 @@ func s2iTestRunner(t *testing.T, testCases []s2iTestCase, f s2iCoFn) { } } -func i2sTestRunner(t *testing.T, testCases []i2sTestCase, f i2sCoFn) { +func int2StringTestRunner(t *testing.T, testCases []int2StringTestCase, f int2StringCoFn) { for _, tt := range testCases { t.Run(tt.in.String(), func(t *testing.T) { @@ -107,7 +107,7 @@ func i2sTestRunner(t *testing.T, testCases []i2sTestCase, f i2sCoFn) { } } -func i2iTestRunner(t *testing.T, testCases []i2iTestCase, f i2iCoFn) { +func int2IntTestRunner(t *testing.T, testCases []int2IntTestCase, f int2IntCoFn) { for _, tt := range testCases { t.Run(tt.in.String(), func(t *testing.T) { @@ -126,7 +126,7 @@ func i2iTestRunner(t *testing.T, testCases []i2iTestCase, f i2iCoFn) { } } -func a2sTestRunner(t *testing.T, testCases []a2sTestCase, f a2sCoFn) { +func any2StringTestRunner(t *testing.T, testCases []any2StringTestCase, f any2StringCoFn) { for _, tt := range testCases { var testName string switch v := tt.in.(type) { @@ -157,7 +157,7 @@ func a2sTestRunner(t *testing.T, testCases []a2sTestCase, f a2sCoFn) { // --- tests --- func TestPatp(t *testing.T) { - var testCases = []a2sTestCase{ + var testCases = []any2StringTestCase{ { in: "0", out: "~zod", @@ -252,11 +252,11 @@ func TestPatp(t *testing.T) { }, } - a2sTestRunner(t, testCases, Patp) + any2StringTestRunner(t, testCases, Patp) } func TestPatq(t *testing.T) { - var testCases = []a2sTestCase{ + var testCases = []any2StringTestCase{ { in: "0", out: "~zod", @@ -351,11 +351,11 @@ func TestPatq(t *testing.T) { }, } - a2sTestRunner(t, testCases, Patq) + any2StringTestRunner(t, testCases, Patq) } func TestClan(t *testing.T) { - var testCases = []s2sTestCase{ + var testCases = []string2StringTestCase{ { in: "~zod", out: ShipClassGalaxy, @@ -410,11 +410,11 @@ func TestClan(t *testing.T) { }, } - s2sTestRunner(t, testCases, Clan) + string2StringTestRunner(t, testCases, Clan) } func TestSein(t *testing.T) { - var testCases = []s2sTestCase{ + var testCases = []string2StringTestCase{ { in: "~zod", out: "~zod", @@ -469,11 +469,11 @@ func TestSein(t *testing.T) { }, } - s2sTestRunner(t, testCases, Sein) + string2StringTestRunner(t, testCases, Sein) } func TestPatp2Dec(t *testing.T) { - var testCases = []s2sTestCase{ + var testCases = []string2StringTestCase{ { out: "0", in: "~zod", @@ -524,11 +524,11 @@ func TestPatp2Dec(t *testing.T) { }, } - s2sTestRunner(t, testCases, Patp2Dec) + string2StringTestRunner(t, testCases, Patp2Dec) } func TestPatq2Dec(t *testing.T) { - var testCases = []s2sTestCase{ + var testCases = []string2StringTestCase{ { out: "0", in: "~zod", @@ -579,11 +579,11 @@ func TestPatq2Dec(t *testing.T) { }, } - s2sTestRunner(t, testCases, Patq2Dec) + string2StringTestRunner(t, testCases, Patq2Dec) } func TestPatp2Hex(t *testing.T) { - var testCases = []s2sTestCase{ + var testCases = []string2StringTestCase{ { out: "00", in: "~zod", @@ -634,11 +634,11 @@ func TestPatp2Hex(t *testing.T) { }, } - s2sTestRunner(t, testCases, Patp2Hex) + string2StringTestRunner(t, testCases, Patp2Hex) } func TestPatq2Hex(t *testing.T) { - var testCases = []s2sTestCase{ + var testCases = []string2StringTestCase{ { out: "00", in: "~zod", @@ -690,11 +690,11 @@ func TestPatq2Hex(t *testing.T) { }, } - s2sTestRunner(t, testCases, Patq2Hex) + string2StringTestRunner(t, testCases, Patq2Hex) } func TestHex2Patp(t *testing.T) { - var testCases = []s2sTestCase{ + var testCases = []string2StringTestCase{ { in: "00", out: "~zod", @@ -745,11 +745,11 @@ func TestHex2Patp(t *testing.T) { }, } - s2sTestRunner(t, testCases, Hex2Patp) + string2StringTestRunner(t, testCases, Hex2Patp) } func TestHex2Patq(t *testing.T) { - var testCases = []s2sTestCase{ + var testCases = []string2StringTestCase{ { in: "00", out: "~zod", @@ -800,11 +800,11 @@ func TestHex2Patq(t *testing.T) { }, } - s2sTestRunner(t, testCases, Hex2Patq) + string2StringTestRunner(t, testCases, Hex2Patq) } func TestPatp2Point(t *testing.T) { - var testCases = []s2iTestCase{ + var testCases = []string2IntTestCase{ { in: "~zod", out: big.NewInt(0), @@ -855,12 +855,12 @@ func TestPatp2Point(t *testing.T) { }, } - s2iTestRunner(t, testCases, Patp2Point) + string2IntTestRunner(t, testCases, Patp2Point) } // Point2Patp func TestPoint2Patp(t *testing.T) { - var testCases = []i2sTestCase{ + var testCases = []int2StringTestCase{ { in: big.NewInt(0), out: "~zod", @@ -907,12 +907,12 @@ func TestPoint2Patp(t *testing.T) { }, } - i2sTestRunner(t, testCases, Point2Patp) + int2StringTestRunner(t, testCases, Point2Patp) } // Patq2Point func TestPatq2Point(t *testing.T) { - var testCases = []s2iTestCase{ + var testCases = []string2IntTestCase{ { in: "~zod", out: big.NewInt(0), @@ -963,12 +963,12 @@ func TestPatq2Point(t *testing.T) { }, } - s2iTestRunner(t, testCases, Patq2Point) + string2IntTestRunner(t, testCases, Patq2Point) } // Point2Patq func TestPoint2Patq(t *testing.T) { - var testCases = []i2sTestCase{ + var testCases = []int2StringTestCase{ { in: big.NewInt(0), out: "~zod", @@ -1015,12 +1015,12 @@ func TestPoint2Patq(t *testing.T) { }, } - i2sTestRunner(t, testCases, Point2Patq) + int2StringTestRunner(t, testCases, Point2Patq) } // SeinPoint func TestSeinPoint(t *testing.T) { - var testCases = []i2iTestCase{ + var testCases = []int2IntTestCase{ { in: big.NewInt(0), out: big.NewInt(0), @@ -1067,12 +1067,12 @@ func TestSeinPoint(t *testing.T) { }, } - i2iTestRunner(t, testCases, SeinPoint) + int2IntTestRunner(t, testCases, SeinPoint) } // ClanPoint func TestClanPoint(t *testing.T) { - var testCases = []i2sTestCase{ + var testCases = []int2StringTestCase{ { in: big.NewInt(0), out: ShipClassGalaxy, @@ -1119,7 +1119,7 @@ func TestClanPoint(t *testing.T) { }, } - i2sTestRunner(t, testCases, ClanPoint) + int2StringTestRunner(t, testCases, ClanPoint) } // TODO: