From bd3f0485950258b0ddf4f9a2dfaf96a2518ea264 Mon Sep 17 00:00:00 2001 From: w6vvn Date: Fri, 5 Sep 2025 17:59:11 -0700 Subject: [PATCH] encapsulate client state in an object --- gem300.rkt | 128 +++-------------------------------------------------- 1 file changed, 5 insertions(+), 123 deletions(-) diff --git a/gem300.rkt b/gem300.rkt index 3bc571b..fa04c6e 100644 --- a/gem300.rkt +++ b/gem300.rkt @@ -1,126 +1,8 @@ #lang racket -(require (prefix-in net: "net.rkt") - (prefix-in gmi: "gmi.rkt")) +(require (prefix-in client: "client.rkt")) -(require net/url-string) - -;; global state variable which will be an input port containing the -;; rendered out gemtext document as it shall be shown to the user -(define document-buffer null) - -;; global state which will be the document structure, before rendering -(define document null) - -;; global state for the url of the currently visited document -(define current-url null) - -(define temporary-failures - '((40 . "temporary failure") - (41 . "server unavailable") - (42 . "CGI error") - (43 . "proxy error") - (44 . "slow down"))) - -(define permanent-failures - '((50 . "permanent failure") - (51 . "not found") - (52 . "gone") - (53 . "proxy request refused") - (59 . "bad request"))) - -(define (get url-str) - (define (iter url-str depth) - (let-values ([(status header c-in) (net:request url-str)]) - ;; TODO there are bunch of other status codes to deal with for - ;; compliance - (cond - ;; clients MUST reject status codes outside of the 10-69 range - [(or (< status 10) - (> status 69)) - (displayln "WARNING: server returned invalid status code")] - - ;; 10-19 INPUT REQUIRED - [(and (>= status 10) - (<= status 19)) - (display "input requested > ") - (get (string-append url-str "?" (read-line)))] - - ;; 20-29 SUCCESS - [(and (>= status 20) - (<= status 29)) - - (let-values ([(doc) (gmi:parse (port->lines c-in))] - [(db-in db-out) (make-pipe #f)]) - - (set! document doc) - - (set! document-buffer db-in) - (parameterize ([current-output-port db-out]) - (gmi:render doc)) - - (set! current-url url-str) - - (let ([remaining (pipe-content-length db-in)]) - (printf "document retrieved. ~a bytes\n" remaining)) - - (next-cmd))] - - ;; 30-39 REDIRECT - [(and (>= status 30) - (<= status 39)) - (if (> depth 5) - (displayln "WARNING: maximum redirection depth exceeded") - (iter header (sub1 depth)))] - - ;; 40-49 TEMPORARY FAILURE - [(and (>= status 40) - (<= status 49)) - (printf "status ~a: ~a\n" status - (dict-ref temporary-failures status "temporary failure"))] - - ;; 50-59 PERMANENT FAILURE - [(and (>= status 50) - (<= status 59)) - (printf "status ~a: ~a\n" status - (dict-ref permanent-failures status "permanent failure"))] - - ;; 60-69 CERTIFICATE REQUIRED - [(and (>= status 60) - (<= status 69)) - (displayln "certificate handling not yet implemented")]))) - - (iter url-str 5)) - -(define (go-cmd url) - (if (non-empty-string? url) - (let () - (when (not (string-contains? url "://")) - (set! url (string-append "gemini://" url))) - - (get url)) - - (displayln "go where?"))) - -(define (next-cmd) - (define (iter depth) - (when (and (> depth 0) - (> (pipe-content-length document-buffer) 0)) - (let () - (displayln (read-line document-buffer)) - (iter (sub1 depth))))) - - (iter 10) - (newline) - (let ([remaining (pipe-content-length document-buffer)]) - (printf "~a bytes remaining\n" remaining))) - -(define (visit-cmd line) - (define url (gmi:match-link document (string->number line))) - (set! url - (url->string (combine-url/relative (string->url current-url) - url))) - (get url)) +(define client (new client:client%)) (define (repl) (display "G-300 > ") @@ -131,15 +13,15 @@ [(or (not matches) (string=? (cadr matches) "next") (string=? (cadr matches) "n")) - (next-cmd)] + (send client next-cmd)] ;; go command [(or (string=? (cadr matches) "go") (string=? (cadr matches) "g")) - (go-cmd (caddr matches))] + (send client go-cmd (caddr matches))] ;; visit link command [(andmap char-numeric? (string->list (cadr matches))) - (visit-cmd (cadr matches))])) + (send client visit-cmd (cadr matches))])) (repl))