-
Notifications
You must be signed in to change notification settings - Fork 0
/
jesty.janet
78 lines (70 loc) · 2.51 KB
/
jesty.janet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
(import http)
(defn fetch-print
```
Simple url fetch. Prints response to the stdout.
Parameter should be table with structure as
returned by the parse-requests fn.
Throws error when fetch fails
```
[{:url url :method method :headers headers :body body}]
(print
((http/request method url {:headers headers :body body}) :body)))
(defn parse-requests
```
Parses src string as request specification.
Returns array with all the parsed requests as tables.
```
[src]
(var common-headers [])
(defn collect-headers [x]
(merge ;(seq [i :in x :when (i :header)] (i :header))))
(defn pdefs [& x] (set common-headers (collect-headers x)))
(defn preq [& x]
(-> {:headers (collect-headers x)}
(merge ;x)
(put :header nil)
(update :headers merge common-headers)))
(defn pnode [tag] (fn [& x] {tag ;x}))
(def request-grammar
(peg/compile
~{:eol "\n"
:header (* (/ (/ (* '(* :w (to ":")) ": " '(to "\n")) ,struct)
,(pnode :header)) :eol)
:definitions (* (/ (* "#" (thru :eol) (some :header)) ,pdefs) :eol)
:title (* (/ (line) ,(pnode :start))
(/ (* "#" (/ '(to :eol) ,string/trim) :eol) ,(pnode :title)))
:method (/ (* '(+ "GET" "POST" "PATCH" "DELETE")) ,(pnode :method))
:url (/ (* '(to :eol)) ,(pnode :url))
:command (* :method " " :url :eol)
:body (/ (* :eol (not "#")
'(some (if-not (* :eol (+ -1 :eol)) 1))
:eol)
,(pnode :body))
:request (/ (* :title :command (any :header) (? :body)
(/ (line) ,(pnode :end)) :eol)
,preq)
:main (* (drop :definitions) (some :request))}))
(:match request-grammar src))
(defn main
```
Program entry point. If called without params,
it parses standart input and execute all
requests specified in it. If parameter line is provided,
only request containing the specified line is executed.
If file parameter is given the program reads from the file
instead of stdin.
Throws error when line is not nunmber.
```
[_ &opt line file]
(def requests
(defer (if file (:close file))
(def src (if file (file/open file) stdin))
(parse-requests (:read src :all))))
(length requests)
(if line
(if-let [i (scan-number line)]
(->> requests
(find |(<= ($ :start) i ($ :end)))
fetch-print)
(error (string "Line must be a nuber, got: " line)))
(loop [r :in requests] (fetch-print r))))