]> Cypherpunks repositories - keks.git/commitdiff
Move human pretty printer to separate file
authorSergey Matveev <stargrave@stargrave.org>
Sun, 13 Apr 2025 12:13:57 +0000 (15:13 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 13 Apr 2025 12:13:59 +0000 (15:13 +0300)
Just for convenience.

go/cmd/pp/main.go
go/cmd/pp/printer.go [new file with mode: 0644]

index bb77ab6cc85ad8f02bc1786de05fc170618ee5b527dc53e9c9ff31e2873806b0..b26c41cae77e1b142b9afb845b8e284c9ba6dfe9066953c918b476828200cb50 100644 (file)
@@ -17,21 +17,15 @@ package main
 
 import (
        "bufio"
-       "encoding/hex"
        "encoding/json"
        "flag"
        "fmt"
        "io"
        "log"
        "os"
-       "slices"
-       "strconv"
        "strings"
-       "time"
 
        "go.cypherpunks.su/keks"
-       "go.cypherpunks.su/keks/types"
-       "go.cypherpunks.su/tai64n/v4"
 )
 
 func usage() {
@@ -60,198 +54,6 @@ var (
        pth []string
 )
 
-func prindent(depth int) {
-       fmt.Print(strings.Repeat("  ", depth))
-}
-
-func hexenc(b []byte) string {
-       return strings.ToUpper(hex.EncodeToString(b))
-}
-
-func printbin(s []byte) {
-       sLen := len(s)
-       var dots string
-       if sLen > int(*MaxStrLen) {
-               s = s[:int(*MaxStrLen)]
-               dots = "..."
-       }
-       if *onlyV {
-               fmt.Println(hexenc(s))
-       } else {
-               fmt.Printf("%s%d:%s%s%s\n", Magenta, sLen, Reset, hexenc(s), dots)
-       }
-}
-
-func isQuiet(where []string) bool {
-       if len(pth) == 0 {
-               return false
-       }
-       if len(pth) > len(where) {
-               return true
-       }
-       return !slices.Equal(where[:len(pth)], pth)
-}
-
-func printer(iter *keks.Iterator, where []string, count int, inList, inMap bool) {
-       var quiet bool
-       for i := range count {
-               if !iter.Next() {
-                       panic("unexpected")
-               }
-               depth := iter.Depth
-               var key string
-               if inMap {
-                       key = iter.Str()
-                       if !iter.Next() {
-                               panic("unexpected")
-                       }
-               }
-               if inList {
-                       where[len(where)-1] = strconv.Itoa(i)
-               } else if inMap {
-                       where[len(where)-1] = key
-               }
-               quiet = isQuiet(where)
-               if !quiet && !*onlyV {
-                       fmt.Print(Blue + strconv.Itoa(depth) + Reset)
-                       fmt.Printf(" %s%03d%s ", Red, iter.Offset(), Reset)
-                       prindent(depth)
-                       if inList {
-                               fmt.Printf("%s%d:%s ", Yellow, i, Reset)
-                       } else if inMap {
-                               fmt.Printf("%s%s:%s ", Green, key, Reset)
-                       }
-               }
-               var listOrMap bool
-               switch iter.T {
-               case types.List:
-                       listOrMap = true
-                       if !quiet && !*onlyV {
-                               fmt.Printf("[ %s%d%s\n", Cyan, iter.Len(), Reset)
-                       }
-                       printer(iter, append(where, "0"), iter.Len(), true, false)
-                       if !quiet && !*onlyV {
-                               prindent(depth)
-                               fmt.Println("     " + " ]")
-                       }
-               case types.Map:
-                       listOrMap = true
-                       if !quiet && !*onlyV {
-                               fmt.Printf("{ %s%d%s\n", Cyan, iter.Len(), Reset)
-                       }
-                       printer(iter, append(where, key), iter.Len(), false, true)
-                       if !quiet && !*onlyV {
-                               prindent(depth)
-                               fmt.Println("     " + " }")
-                       }
-               }
-               if listOrMap || quiet {
-                       continue
-               }
-               switch iter.T {
-               case types.NIL:
-                       fmt.Println("NIL")
-               case types.Bool:
-                       if iter.Bool() {
-                               fmt.Println("TRUE")
-                       } else {
-                               fmt.Println("FALSE")
-                       }
-               case types.Hexlet:
-                       h := iter.Hexlet()
-                       if *onlyV {
-                               fmt.Println(h.UUID())
-                       } else {
-                               fmt.Println(h.UUID(), h.IP())
-                       }
-               case types.UInt:
-                       fmt.Println(iter.UInt())
-               case types.Int:
-                       fmt.Println(iter.Int())
-               case types.BigInt:
-                       fmt.Println(iter.BigInt())
-               case types.Blob:
-                       blob := iter.Blob()
-                       if *onlyV {
-                               v, err := io.ReadAll(blob.Reader())
-                               if err != nil {
-                                       log.Fatal(err)
-                               }
-                               fmt.Println(hex.EncodeToString(v))
-                               break
-                       }
-                       fmt.Printf("BLOB[ %s%d l=%d%s\n",
-                               Cyan, len(blob.Chunks), blob.ChunkLen, Reset)
-                       off := iter.Offset() + 1 + 8
-                       for i, chunk := range blob.Chunks {
-                               fmt.Print(Blue + strconv.Itoa(depth+1) + Reset)
-                               fmt.Printf(" %s%03d%s ", Red, off, Reset)
-                               prindent(depth + 1)
-                               fmt.Printf("%s%d:%s ", Yellow, i, Reset)
-                               printbin([]byte(chunk))
-                               off += int64(len(chunk)) + 1
-                       }
-                       prindent(depth)
-                       fmt.Println("     " + " ]")
-               case types.TAI64:
-                       t := iter.TAI64().Time()
-                       utc, isLeap := tai64n.Leapsecs.Sub(t)
-                       if isLeap {
-                               fmt.Printf("TAI64(%s TAI, leap)\n", t.Format(time.DateTime))
-                       } else {
-                               fmt.Printf("TAI64(%s TAI, %s UTC)\n",
-                                       t.Format(time.DateTime), utc.Format(time.DateTime))
-                       }
-               case types.TAI64N:
-                       t := iter.TAI64N().Time()
-                       utc, isLeap := tai64n.Leapsecs.Sub(t)
-                       if isLeap {
-                               fmt.Printf("TAI64N(%s TAI, leap)\n",
-                                       t.Format(time.DateTime+".000000000"))
-                       } else {
-                               fmt.Printf("TAI64N(%s TAI, %s UTC)\n",
-                                       t.Format(time.DateTime+".000000000"),
-                                       utc.Format(time.DateTime+".000000000"))
-                       }
-               case types.TAI64NA:
-                       t := iter.TAI64NA()
-                       fmt.Printf("TAI64NA(%s)\n", hexenc(t[:]))
-               case types.Magic:
-                       var builder strings.Builder
-                       for _, b := range []byte(iter.Magic()) {
-                               if strconv.IsPrint(rune(b)) {
-                                       builder.WriteByte(b)
-                               } else {
-                                       builder.WriteString(fmt.Sprintf("\\x%02x", b))
-                               }
-                       }
-                       fmt.Printf("Magic(%s)\n", builder.String())
-               case types.Bin:
-                       printbin(iter.Bin())
-               case types.Str:
-                       if !*onlyV {
-                               fmt.Print(`"`)
-                       }
-                       s := iter.Str()
-                       sLen := len(s)
-                       if sLen > int(*MaxStrLen) {
-                               fmt.Print(s[:int(*MaxStrLen)])
-                               fmt.Print("...")
-                       } else {
-                               fmt.Print(s)
-                       }
-                       if !*onlyV {
-                               fmt.Print(`"`)
-                       }
-                       fmt.Println("")
-               case types.Raw:
-                       fmt.Printf("(l=%d v=%s)\n", len(iter.Raw()), hexenc(iter.Raw()))
-               default:
-                       fmt.Println("???")
-               }
-       }
-}
-
 func main() {
        flag.Usage = usage
        flag.Parse()
diff --git a/go/cmd/pp/printer.go b/go/cmd/pp/printer.go
new file mode 100644 (file)
index 0000000..6d91d5c
--- /dev/null
@@ -0,0 +1,223 @@
+// pp -- KEKS pretty printer
+// Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, version 3 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+package main
+
+import (
+       "encoding/hex"
+       "fmt"
+       "io"
+       "log"
+       "slices"
+       "strconv"
+       "strings"
+       "time"
+
+       "go.cypherpunks.su/keks"
+       "go.cypherpunks.su/keks/types"
+       "go.cypherpunks.su/tai64n/v4"
+)
+
+func isQuiet(where []string) bool {
+       if len(pth) == 0 {
+               return false
+       }
+       if len(pth) > len(where) {
+               return true
+       }
+       return !slices.Equal(where[:len(pth)], pth)
+}
+
+func prindent(depth int) {
+       fmt.Print(strings.Repeat("  ", depth))
+}
+
+func hexenc(b []byte) string {
+       return strings.ToUpper(hex.EncodeToString(b))
+}
+
+func printbin(s []byte) {
+       sLen := len(s)
+       var dots string
+       if sLen > int(*MaxStrLen) {
+               s = s[:int(*MaxStrLen)]
+               dots = "..."
+       }
+       if *onlyV {
+               fmt.Println(hexenc(s))
+       } else {
+               fmt.Printf("%s%d:%s%s%s\n", Magenta, sLen, Reset, hexenc(s), dots)
+       }
+}
+
+func printer(iter *keks.Iterator, where []string, count int, inList, inMap bool) {
+       var quiet bool
+       for i := range count {
+               if !iter.Next() {
+                       panic("unexpected")
+               }
+               depth := iter.Depth
+               var key string
+               if inMap {
+                       key = iter.Str()
+                       if !iter.Next() {
+                               panic("unexpected")
+                       }
+               }
+               if inList {
+                       where[len(where)-1] = strconv.Itoa(i)
+               } else if inMap {
+                       where[len(where)-1] = key
+               }
+               quiet = isQuiet(where)
+               if !quiet && !*onlyV {
+                       fmt.Print(Blue + strconv.Itoa(depth) + Reset)
+                       fmt.Printf(" %s%03d%s ", Red, iter.Offset(), Reset)
+                       prindent(depth)
+                       if inList {
+                               fmt.Printf("%s%d:%s ", Yellow, i, Reset)
+                       } else if inMap {
+                               fmt.Printf("%s%s:%s ", Green, key, Reset)
+                       }
+               }
+               var listOrMap bool
+               switch iter.T {
+               case types.List:
+                       listOrMap = true
+                       if !quiet && !*onlyV {
+                               fmt.Printf("[ %s%d%s\n", Cyan, iter.Len(), Reset)
+                       }
+                       printer(iter, append(where, "0"), iter.Len(), true, false)
+                       if !quiet && !*onlyV {
+                               prindent(depth)
+                               fmt.Println("     " + " ]")
+                       }
+               case types.Map:
+                       listOrMap = true
+                       if !quiet && !*onlyV {
+                               fmt.Printf("{ %s%d%s\n", Cyan, iter.Len(), Reset)
+                       }
+                       printer(iter, append(where, key), iter.Len(), false, true)
+                       if !quiet && !*onlyV {
+                               prindent(depth)
+                               fmt.Println("     " + " }")
+                       }
+               }
+               if listOrMap || quiet {
+                       continue
+               }
+               switch iter.T {
+               case types.NIL:
+                       fmt.Println("NIL")
+               case types.Bool:
+                       if iter.Bool() {
+                               fmt.Println("TRUE")
+                       } else {
+                               fmt.Println("FALSE")
+                       }
+               case types.Hexlet:
+                       h := iter.Hexlet()
+                       if *onlyV {
+                               fmt.Println(h.UUID())
+                       } else {
+                               fmt.Println(h.UUID(), h.IP())
+                       }
+               case types.UInt:
+                       fmt.Println(iter.UInt())
+               case types.Int:
+                       fmt.Println(iter.Int())
+               case types.BigInt:
+                       fmt.Println(iter.BigInt())
+               case types.Blob:
+                       blob := iter.Blob()
+                       if *onlyV {
+                               v, err := io.ReadAll(blob.Reader())
+                               if err != nil {
+                                       log.Fatal(err)
+                               }
+                               fmt.Println(hex.EncodeToString(v))
+                               break
+                       }
+                       fmt.Printf("BLOB[ %s%d l=%d%s\n",
+                               Cyan, len(blob.Chunks), blob.ChunkLen, Reset)
+                       off := iter.Offset() + 1 + 8
+                       for i, chunk := range blob.Chunks {
+                               fmt.Print(Blue + strconv.Itoa(depth+1) + Reset)
+                               fmt.Printf(" %s%03d%s ", Red, off, Reset)
+                               prindent(depth + 1)
+                               fmt.Printf("%s%d:%s ", Yellow, i, Reset)
+                               printbin([]byte(chunk))
+                               off += int64(len(chunk)) + 1
+                       }
+                       prindent(depth)
+                       fmt.Println("     " + " ]")
+               case types.TAI64:
+                       t := iter.TAI64().Time()
+                       utc, isLeap := tai64n.Leapsecs.Sub(t)
+                       if isLeap {
+                               fmt.Printf("TAI64(%s TAI, leap)\n", t.Format(time.DateTime))
+                       } else {
+                               fmt.Printf("TAI64(%s TAI, %s UTC)\n",
+                                       t.Format(time.DateTime), utc.Format(time.DateTime))
+                       }
+               case types.TAI64N:
+                       t := iter.TAI64N().Time()
+                       utc, isLeap := tai64n.Leapsecs.Sub(t)
+                       if isLeap {
+                               fmt.Printf("TAI64N(%s TAI, leap)\n",
+                                       t.Format(time.DateTime+".000000000"))
+                       } else {
+                               fmt.Printf("TAI64N(%s TAI, %s UTC)\n",
+                                       t.Format(time.DateTime+".000000000"),
+                                       utc.Format(time.DateTime+".000000000"))
+                       }
+               case types.TAI64NA:
+                       t := iter.TAI64NA()
+                       fmt.Printf("TAI64NA(%s)\n", hexenc(t[:]))
+               case types.Magic:
+                       var builder strings.Builder
+                       for _, b := range []byte(iter.Magic()) {
+                               if strconv.IsPrint(rune(b)) {
+                                       builder.WriteByte(b)
+                               } else {
+                                       builder.WriteString(fmt.Sprintf("\\x%02x", b))
+                               }
+                       }
+                       fmt.Printf("Magic(%s)\n", builder.String())
+               case types.Bin:
+                       printbin(iter.Bin())
+               case types.Str:
+                       if !*onlyV {
+                               fmt.Print(`"`)
+                       }
+                       s := iter.Str()
+                       sLen := len(s)
+                       if sLen > int(*MaxStrLen) {
+                               fmt.Print(s[:int(*MaxStrLen)])
+                               fmt.Print("...")
+                       } else {
+                               fmt.Print(s)
+                       }
+                       if !*onlyV {
+                               fmt.Print(`"`)
+                       }
+                       fmt.Println("")
+               case types.Raw:
+                       fmt.Printf("(l=%d v=%s)\n", len(iter.Raw()), hexenc(iter.Raw()))
+               default:
+                       fmt.Println("???")
+               }
+       }
+}