summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Halloway <stu@thinkrelevance.com>2010-04-23 16:50:45 -0400
committerStuart Halloway <stu@thinkrelevance.com>2010-04-24 14:29:09 -0400
commitc487e48a65ee7cef66ef017c87a754fc88ba57e0 (patch)
tree8271d576ef08b0ed23a0ba43b55db42e333ca1d2
parente0e0b6a2f192bf743e3629dff0b23a39ccf4f8db (diff)
java.util.Map for defrecord, #313
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
-rw-r--r--src/clj/clojure/core_deftype.clj19
-rw-r--r--test/clojure/test_clojure/protocols.clj21
2 files changed, 38 insertions, 2 deletions
diff --git a/src/clj/clojure/core_deftype.clj b/src/clj/clojure/core_deftype.clj
index 6e1d8d7e..0a90356e 100644
--- a/src/clj/clojure/core_deftype.clj
+++ b/src/clj/clojure/core_deftype.clj
@@ -196,8 +196,23 @@
`(without [~'this ~'k] (if (contains? #{~@(map keyword base-fields)} ~'k)
(dissoc (with-meta (into {} ~'this) ~'__meta) ~'k)
(new ~tagname ~@(remove #{'__extmap} fields)
- (not-empty (dissoc ~'__extmap ~'k))))))])]
- (let [[i m] (-> [interfaces methods] eqhash iobj ilookup imap)]
+ (not-empty (dissoc ~'__extmap ~'k))))))])
+ (ijavamap [[i m]]
+ [(conj i 'java.util.Map)
+ (conj m
+ `(size [~'this] (.count ~'this))
+ `(isEmpty [~'this] (= 0 (.count ~'this)))
+ `(containsValue [~'this ~'v] (-> ~'this vals (.contains ~'v)))
+ `(get [~'this ~'k] (.valAt ~'this ~'k))
+ `(put [~'this ~'k ~'v] (throw (UnsupportedOperationException.)))
+ `(remove [~'this ~'k] (throw (UnsupportedOperationException.)))
+ `(putAll [~'this ~'m] (throw (UnsupportedOperationException.)))
+ `(clear [~'this] (throw (UnsupportedOperationException.)))
+ `(keySet [~'this] (set (keys ~'this)))
+ `(values [~'this] (vals ~'this))
+ `(entrySet [~'this] (set ~'this)))])
+ ]
+ (let [[i m] (-> [interfaces methods] eqhash iobj ilookup imap ijavamap)]
`(deftype* ~tagname ~classname ~(conj hinted-fields '__meta '__extmap)
:implements ~(vec i)
~@m)))))
diff --git a/test/clojure/test_clojure/protocols.clj b/test/clojure/test_clojure/protocols.clj
index 7f678234..a98994f3 100644
--- a/test/clojure/test_clojure/protocols.clj
+++ b/test/clojure/test_clojure/protocols.clj
@@ -30,6 +30,7 @@
(map #(.getName %))
(sort)))
+(defrecord EmptyRecord [])
(defrecord TestRecord [a b])
(defn r
([a b] (TestRecord. a b))
@@ -157,6 +158,26 @@
(is (= (r 1 3 {} {:c 4}) (merge rec {:b 3 :c 4})))))
(deftest defrecord-interfaces-test
+ (testing "java.util.Map"
+ (let [rec (r 1 2)]
+ (is (= 2 (.size rec)))
+ (is (= 3 (.size (assoc rec :c 3))))
+ (is (not (.isEmpty rec)))
+ (is (.isEmpty (EmptyRecord.)))
+ (is (.containsKey rec :a))
+ (is (not (.containsKey rec :c)))
+ (is (.containsValue rec 1))
+ (is (not (.containsValue rec 3)))
+ (is (= 1 (.get rec :a)))
+ (is (thrown? UnsupportedOperationException (.put rec :a 1)))
+ (is (thrown? UnsupportedOperationException (.remove rec :a)))
+ (is (thrown? UnsupportedOperationException (.putAll rec {})))
+ (is (thrown? UnsupportedOperationException (.clear rec)))
+ (is (= #{:a :b} (.keySet rec)))
+ (is (= #{1 2} (set (.values rec))))
+ (is (= #{[:a 1] [:b 2]} (.entrySet rec)))
+
+ ))
(testing "IPersistentCollection"
(testing ".cons"
(let [rec (r 1 2)]