From 697c9d26e27e95c9beafc6d3616b16ad18d2fcc9 Mon Sep 17 00:00:00 2001 From: Greg Date: Tue, 12 Jul 2022 03:29:37 +0900 Subject: [PATCH] don't panic, support swi dicts --- client.go | 1 + prolog.go | 2 +- send.go | 5 +++++ term.go | 31 +++++++++++++++++++++++-------- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/client.go b/client.go index 3681531..f1bfc06 100644 --- a/client.go +++ b/client.go @@ -67,6 +67,7 @@ func (c Client) create(ctx context.Context, query string, destroy bool) (*Engine if query != "" { opts.Ask = query } + opts.Destroy = destroy evt, err := eng.post(ctx, "create", opts) if err != nil { diff --git a/prolog.go b/prolog.go index 519c54d..0aae5b7 100644 --- a/prolog.go +++ b/prolog.go @@ -92,7 +92,7 @@ func (p *prologAnswers) handle(ctx context.Context, a string) error { parser := defaultInterpreter.Parser(strings.NewReader(a), nil) t, err := parser.Term() if err != nil { - panic(err) + return fmt.Errorf("pengines: failed to parse response: %w", err) } event, ok := t.(*engine.Compound) diff --git a/send.go b/send.go index 97ed158..70ed1e2 100644 --- a/send.go +++ b/send.go @@ -95,6 +95,11 @@ func (e *Engine) post(ctx context.Context, action string, body any) (answer, err } defer resp.Body.Close() + // if e.debug { + // rrr, _ := httputil.DumpResponse(resp, true) + // fmt.Println("GOT: ", string(rrr)) + // } + if resp.StatusCode != http.StatusOK { return v, fmt.Errorf("bad status: %d", resp.StatusCode) } diff --git a/term.go b/term.go index f61ea79..ce745a8 100644 --- a/term.go +++ b/term.go @@ -25,13 +25,14 @@ type Solution map[string]Term // One of the fields should be "truthy". // This can be handy for parsing query results in JSON format. type Term struct { - Atom *string - Number *json.Number - Compound *Compound - Variable *string - Boolean *bool - List []Term - Null bool + Atom *string + Number *json.Number + Compound *Compound + Variable *string + Boolean *bool + List []Term + Dictionary map[string]Term + Null bool } // UnmarshalJSON implements json.Unmarshaler. @@ -62,7 +63,21 @@ func (t *Term) UnmarshalJSON(b []byte) error { case []any: return json.Unmarshal(b, &t.List) case map[string]any: - return json.Unmarshal(b, &t.Compound) + if _, ok := x["functor"]; ok { + return json.Unmarshal(b, &t.Compound) + } + rawDict := make(map[string]json.RawMessage, len(x)) + if err := json.Unmarshal(b, &rawDict); err != nil { + return err + } + t.Dictionary = make(map[string]Term, len(rawDict)) + for k, raw := range rawDict { + var v Term + if err := json.Unmarshal(raw, &v); err != nil { + return err + } + t.Dictionary[k] = v + } case nil: t.Null = true default: