]> Cypherpunks repositories - keks.git/commitdiff
Less panics, more checks
authorSergey Matveev <stargrave@stargrave.org>
Fri, 4 Apr 2025 10:05:55 +0000 (13:05 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Fri, 4 Apr 2025 10:05:55 +0000 (13:05 +0300)
go/schema/check.go

index 9143eab61d47ab452e1a15d62ca9c628855069c78aa5c9e5f35726341824524e..6b48831571529866d49e158d2d8db0b5a8ece01988cb8181d2910d3d031db567 100644 (file)
@@ -47,7 +47,14 @@ func Check(schemaName string, schemas map[string][][]any, data any) error {
        var single bool // TAKEn, not EACH
        var vs []any
        for i, act := range acts {
-               switch cmd := act[0].(string); cmd {
+               if len(act) == 0 {
+                       return fmt.Errorf("%s: %d: empty command", schemaName, i)
+               }
+               cmd, ok := act[0].(string)
+               if !ok {
+                       return fmt.Errorf("%s: %d: non command: %+v", schemaName, i, act[0])
+               }
+               switch cmd {
                case CmdExists:
                        if vs == nil {
                                return fmt.Errorf("%s: %d: %s", schemaName, i, cmd)
@@ -58,6 +65,9 @@ func Check(schemaName string, schemas map[string][][]any, data any) error {
                        }
                case CmdTake:
                        single = true
+                       if len(act) != 2 {
+                               return fmt.Errorf("%s: %d: %s: wrong number of args", schemaName, i, cmd)
+                       }
                        switch k := act[1].(type) {
                        case string:
                                if k == "." {
@@ -75,7 +85,7 @@ func Check(schemaName string, schemas map[string][][]any, data any) error {
                                l := data.([]any)
                                vs = []any{l[k]}
                        default:
-                               panic("bad take target")
+                               return fmt.Errorf("%s: %d: %s: bad target", schemaName, i, cmd)
                        }
                case CmdEach:
                        single = false
@@ -99,8 +109,15 @@ func Check(schemaName string, schemas map[string][][]any, data any) error {
                                continue
                        }
                        expected := make([]types.Type, 0, len(act)-1)
-                       for _, t := range act[1:] {
-                               switch t := t.(string); t {
+                       if len(act) < 2 {
+                               return fmt.Errorf("%s: %d: %s: wrong number of args", schemaName, i, cmd)
+                       }
+                       for _, tAny := range act[1:] {
+                               t, ok := tAny.(string)
+                               if !ok {
+                                       return fmt.Errorf("%s: %d: %s: non-str: %+v", schemaName, i, cmd, tAny)
+                               }
+                               switch t {
                                case "NIL":
                                        expected = append(expected, types.NIL)
                                case "BOOL":
@@ -124,7 +141,7 @@ func Check(schemaName string, schemas map[string][][]any, data any) error {
                                case "STR":
                                        expected = append(expected, types.Str)
                                default:
-                                       panic("unknown type: " + t)
+                                       return fmt.Errorf("%s: %d: %s: unknown type: %s", schemaName, i, cmd, t)
                                }
                        }
                        var typ types.Type
@@ -161,7 +178,7 @@ func Check(schemaName string, schemas map[string][][]any, data any) error {
                                case keks.Raw:
                                        typ = types.Raw
                                default:
-                                       panic(fmt.Errorf("unsupported type: %+v", v))
+                                       return fmt.Errorf("%s: %d: %s: unsupported type: %T", schemaName, i, cmd, v)
                                }
                                if !slices.Contains(expected, typ) {
                                        return fmt.Errorf("%s: %d: %d: %s: %T", schemaName, i, n, cmd, v)
@@ -172,13 +189,16 @@ func Check(schemaName string, schemas map[string][][]any, data any) error {
                                continue
                        }
                        var expect int64
+                       if len(act) != 2 {
+                               return fmt.Errorf("%s: %d: %s: wrong number of args", schemaName, i, cmd)
+                       }
                        switch v := act[1].(type) {
                        case uint64:
                                expect = int64(v)
                        case int64:
                                expect = v
                        default:
-                               panic(fmt.Errorf("unsupported type: %+v", v))
+                               return fmt.Errorf("%s: %d: %s: unsupported type: %T", schemaName, i, cmd, v)
                        }
                        for _, v := range vs {
                                var got int64
@@ -197,7 +217,7 @@ func Check(schemaName string, schemas map[string][][]any, data any) error {
                                        case int64:
                                                got = v
                                        default:
-                                               panic("non len-able")
+                                               return fmt.Errorf("%s: %d: %s: non len-able: %T", schemaName, i, cmd, v)
                                        }
                                }
                                switch cmd {
@@ -215,13 +235,20 @@ func Check(schemaName string, schemas map[string][][]any, data any) error {
                        if vs == nil {
                                continue
                        }
+                       if len(act) != 2 {
+                               return fmt.Errorf("%s: %d: %s: wrong number of args", schemaName, i, cmd)
+                       }
+                       name, ok := act[1].(string)
+                       if !ok {
+                               return fmt.Errorf("%s: %d: %s: bad name: %+v", schemaName, i, cmd, act[1])
+                       }
                        for n, v := range vs {
-                               if err := Check(act[1].(string), schemas, v); err != nil {
+                               if err := Check(name, schemas, v); err != nil {
                                        return fmt.Errorf("%s: %d: %d: %s: %w", schemaName, i, n, cmd, err)
                                }
                        }
                default:
-                       panic("unknown command: " + cmd)
+                       return fmt.Errorf("%s: %d: %s: unknown command", schemaName, i, cmd)
                }
        }
        return nil