This repository has been archived by the owner on Mar 12, 2024. It is now read-only.
/
bitfield.clj
56 lines (54 loc) · 1.82 KB
/
bitfield.clj
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
(ns celtuce.args.bitfield
(:import
(io.lettuce.core
BitFieldArgs
BitFieldArgs$BitFieldType
BitFieldArgs$OverflowType)))
(defn ^BitFieldArgs$BitFieldType bft
"Constructs a BitFieldType from a keyword"
[bft-kw]
(if-let [[_ sign bits] (re-find #"(^[us])(\d+)$" ((fnil name "") bft-kw))]
(case sign
"s" (BitFieldArgs/signed (Integer/parseInt bits))
"u" (BitFieldArgs/unsigned (Integer/parseInt bits)))
(throw
(ex-info "invalid bitfield type keyword"
{:value bft-kw :valid #"(^[us])(\d+)$"}))))
(defn bitfield-args
"Constructs a BitFieldArgs from a chain of commands"
[& commands]
(loop [args (BitFieldArgs.)
[sub & tail] commands]
(case sub
:overflow
(let [[behavior & tail] tail]
(case behavior
:wrap (.overflow args BitFieldArgs$OverflowType/WRAP)
:sat (.overflow args BitFieldArgs$OverflowType/SAT)
:fail (.overflow args BitFieldArgs$OverflowType/FAIL)
(throw
(ex-info "invalid :overflow"
{:value behavior :valid #{:wrap :sat :fail}})))
(if (nil? tail)
(throw
(ex-info (str "no sub-command after :overflow " behavior)
{:value tail :valid #{:get :set :incrby}}))
(recur args tail)))
:get
(let [[bft-kw offset & tail] tail]
(.get args (bft bft-kw) ^int offset)
(if (nil? tail)
args
(recur args tail)))
:set
(let [[bft-kw offset value & tail] tail]
(.set args (bft bft-kw) ^int offset ^long value)
(if (nil? tail)
args
(recur args tail)))
:incrby
(let [[bft-kw offset amount & tail] tail]
(.incrBy args (bft bft-kw) ^int offset ^long amount)
(if (nil? tail)
args
(recur args tail))))))