From 01b75599a500d6276a962b47744166abb25d846c Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Tue, 28 Apr 2026 19:13:05 -0500 Subject: refactor: switch gloss-fetch result to uniform plist shape MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous shape (:ok DEFS) | (:empty :no-defs (...) :failed (...)) was malformed as a plist. The :empty tag at position 0 shifted the plist alignment. plist-get on :no-defs or :failed returned nil. Tests had to use (plist-get (cdr result) ...) as a workaround. The new shape is a uniform plist with all three keys always present: (:defs DEFS :no-defs (SYM ...) :failed (SYM ...)). Consumers branch on whether :defs is non-empty. There is no tag. plist-get works uniformly across success and empty cases. Updated gloss-fetch.el (rollup function and docstrings), 7 test files, and the design doc (docs/design/gloss.org § Error Handling). Tested by `make test`. 65 tests pass in 0.36 seconds. --- docs/design/gloss.org | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'docs/design/gloss.org') diff --git a/docs/design/gloss.org b/docs/design/gloss.org index 04efc38..649eb24 100644 --- a/docs/design/gloss.org +++ b/docs/design/gloss.org @@ -183,21 +183,22 @@ After =gloss-drill-export-all=, the heading line gains a =:drill:= tag and the p *=:reason= strings* carry the technical detail (=timeout (5s)=, =HTTP 503=, =malformed JSON: ...=) and land in =*gloss-debug*=. They are never user-facing. -*User-facing rollup.* =gloss-fetch-definitions= aggregates per-source results into: +*User-facing rollup.* =gloss-fetch-definitions= returns a uniform plist with three keys, all always present: #+begin_src emacs-lisp -(:ok DEFS) ;; any source returned >=1 def -(:empty :no-defs (...) :failed (...)) ;; everything else +(:defs DEFS ;; possibly-empty list of definition plists + :no-defs (SYM ...) ;; sources reached but returning no defs + :failed (SYM ...)) ;; sources that could not be reached #+end_src -=:failed= unions =:unreachable=, =:server-error=, =:rate-limited=. +=:failed= unions =:unreachable=, =:server-error=, =:rate-limited=. Consumers branch on whether =(plist-get result :defs)= is non-empty. | Result shape | Message | |-------------------------------------------+--------------------------------------------------------------------| -| Every source =:no-defs=, none failed | "No definition for X in Wiktionary." | -| Every source failed, none =:no-defs= | "Couldn't reach Wiktionary." | -| Mix of =:no-defs= and failures | "No definition in Wiktionary; couldn't reach DictionaryAPI." | -| Any =:ok= with defs | Silent on others — picker shows what came back | +| =:defs= empty, only =:no-defs= populated | "No definition for X in Wiktionary." | +| =:defs= empty, only =:failed= populated | "Couldn't reach Wiktionary." | +| =:defs= empty, both populated | "No definition in Wiktionary; couldn't reach DictionaryAPI." | +| =:defs= non-empty | Silent on others — picker shows what came back | When v2 starts surfacing =:rate-limited= regularly, the rollup wording will gain a third visible category. v1 with no-key Wiktionary doesn't need it. -- cgit v1.2.3