Skip to content

Instantly share code, notes, and snippets.

@namenu
Created August 20, 2022 15:00
Show Gist options
  • Save namenu/00fc45088d781ee73e841e6feb2f936b to your computer and use it in GitHub Desktop.
Save namenu/00fc45088d781ee73e841e6feb2f936b to your computer and use it in GitHub Desktop.
(ns scratchpad.relay-protocol)
(defprotocol Connection
(next-page [_ opts])
(previous-page [_ opts])
(has-next-page [_ opts])
(has-previous-page [_ opts]))
(defn vector->Connection [v]
(let [cursor->idx parse-long]
(reify
Connection
(next-page [_ {:keys [first after]}]
(let [idx (cursor->idx after)]
(->> v
(drop idx)
(take first))))
(previous-page [_ {:keys [last before]}]
(let [idx (- (cursor->idx before) last)
[d t] (if (neg-int? idx)
[0 (+ last idx)]
[idx last])]
(->> v
(drop d)
(take t))))
(has-next-page [_ {:keys [before after first]}]
(cond
first (let [b-idx (cursor->idx before)
a-idx (cursor->idx after)
count (- b-idx a-idx)]
(>= count first))
before (let [b-idx (cursor->idx before)]
(< b-idx (dec (count v))))
:else false))
(has-previous-page [_ {:keys [before after last]}]
(cond
last (let [b-idx (cursor->idx before)
a-idx (cursor->idx after)
count (- b-idx a-idx)]
(>= count last))
after (let [a-idx (cursor->idx after)]
(> a-idx 0))
:else false)))))
(require '[clojure.test :refer [deftest testing is run-tests]])
(deftest vector-connection
(testing ""
(let [data [1 2 3 4 5 6 7 8 9 10]
c (vector->Connection data)]
;; data(first: 3, after: "3") => [4 5 6]
(is (= (next-page c {:first 3 :after "3"})
'(4 5 6)))
;; data(last: 2, before: "3") => [2 3]
(is (= (previous-page c {:last 2 :before "3"})
'(2 3)))
(is (false? (has-next-page c {})))
(is (true? (has-next-page c {:before "0"})))
(is (false? (has-next-page c {:before "9"})))
(is (false? (has-previous-page c {})))
(is (true? (has-previous-page c {:after "1"})))
(is (false? (has-previous-page c {:after "0"})))
)))
(run-tests)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment