Blob


1 # gemini.core
3 A Clojure library to make Gemini requests that exposes some low-level
4 API to handle network requests.
7 ## Usage
9 Import the library for e.g. with:
11 ```clojure
12 user=> (require '[gemini.core :as gemini])
13 ```
15 ### Documentation
17 `fetch` makes a Gemini request and returns a map with `:request`,
18 `:meta`, `:code` and `:body` as keys, or `:error` if an error occur.
20 The request needs to be closed afterwards using `close`.
22 ```clojure
23 user=> (gemini/fetch "gemini://gemini.circumlunar.space/")
24 {:request
25 #object[com.omarpolo.gemini.Request 0x3b270767 "com.omarpolo.gemini.Request@3b270767"],
26 :meta "gemini://gemini.circumlunar.space/",
27 :code 31,
28 :body
29 #object[java.io.BufferedReader 0x49358b66 "java.io.BufferedReader@49358b66"]}
30 ```
32 `body-as-string!` reads all the response into a string and returns it.
33 It also closes the request automatically.
35 ```clojure
36 user=> (-> (gemini/fetch "gemini://gemini.circumlunar.space/")
37 gemini/body-as-string!)
38 "# Project Gemini\n\n## Overview\n\nGemini is a new internet protocol which..."
39 ```
41 `close` closes a request. It needs to be called after every
42 (successful) request.
44 ```clojure
45 user=> (let [req (gemini/fetch "...")]
46 (when-not (:error req)
47 ;; do something with req
48 ,,,
49 (gemini/close req)))
50 ```
52 `with-request` is a macro like `with-open` to making connection
53 easily. It automatically closes the request and evaluates the body
54 only when the request is successful, otherwise throws an exception.
56 ```clojure
57 user=> (with-request [req (gemini/fetch "gemini://gemini.circumlunar.space/")]
58 ,,,)
59 ```
62 ## Streaming content
64 The `:body` keyword in the returned map is an instance of a Java
65 BufferedReader, so streaming content is easy.
67 However, `body-as-string!` needs to materialise the full reply, so in
68 case of a streaming request it will never return!
71 ## text/gemini
73 This library only implements the network part of Gemini, it doesn't
74 try to handle any kind of content. To handle text/gemini you can use
75 e.g. the [gemtext][gemtext] library:
77 ```clojure
78 user=> (require '[gemtext.core :as gemtext])
79 nil
80 user=> (gemini/with-request [req (gemini/fetch "gemini://gemini.circumlunar.space/")]
81 (gemtext/parse (:body req)))
82 [[:header-1 "Project Gemini"]
83 [:text ""]
84 [:header-2 "Overview"]
85 [:text ""]
86 [:text "Gemini is a new internet protocol which:"]
87 ,,,]
88 ```
90 The [gemtext][gemtext] library supports streaming via the
91 `gemtext.core/parse` transducer:
93 ```clojure
94 user=> (gemini/with-request [req (gemini/fetch "gemini://gemini.circumlunar.space/")]
95 (transduce gemtext/parser conj [] (line-seq (:body req))))
96 ,,,
97 ```
100 [gemtext]: https://github.com/omar-polo/gemtext