Skip to content

Commit fcc4495

Browse files
committed
CLJS-2929: Port datafy
1 parent 8ceee7f commit fcc4495

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

src/main/cljs/cljs/core.cljs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,13 @@
867867
(-iterator [coll]
868868
"Returns an iterator for coll."))
869869

870+
(defprotocol IDatafiable
871+
(-datafy [o] "return a representation of o as data (default identity)"))
872+
873+
(defprotocol INavigable
874+
(-nav [coll k v] "return (possibly transformed) v in the context of coll and k (a key/index or nil),
875+
defaults to returning v."))
876+
870877
;; Printing support
871878

872879
(deftype StringBufferWriter [sb]
@@ -1356,7 +1363,10 @@
13561363

13571364
(extend-type nil
13581365
ICounted
1359-
(-count [_] 0))
1366+
(-count [_] 0)
1367+
1368+
IDatafiable
1369+
(-datafy [_] nil))
13601370

13611371
;; TODO: we should remove this and handle date equality checking
13621372
;; by some other means, probably by adding a new primitive type
@@ -1405,7 +1415,13 @@
14051415
(extend-type default
14061416
IHash
14071417
(-hash [o]
1408-
(goog/getUid o)))
1418+
(goog/getUid o))
1419+
1420+
IDatafiable
1421+
(-datafy [o] o)
1422+
1423+
INavigable
1424+
(-nav [_ _ x] x))
14091425

14101426
;;this is primitive because & emits call to array-seq
14111427
(defn inc

src/main/cljs/clojure/datafy.cljs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
; Copyright (c) Rich Hickey. All rights reserved.
2+
; The use and distribution terms for this software are covered by the
3+
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+
; which can be found in the file epl-v10.html at the root of this distribution.
5+
; By using this software in any fashion, you are agreeing to be bound by
6+
; the terms of this license.
7+
; You must not remove this notice, or any other, from this software.
8+
9+
(ns
10+
^{:doc "Functions to turn objects into data. Alpha, subject to change"}
11+
clojure.datafy)
12+
13+
(defn datafy
14+
"Attempts to return x as data. If :clojure.datafy/datafy is present
15+
as metadata of x, it will be called with x as an argument, else
16+
datafy will return the value of clojure.protocols/datafy. If the
17+
value has been transformed and the result supports
18+
metadata, :clojure.datafy/obj will be set on the metadata to the
19+
original value of x."
20+
[x]
21+
(let [v ((or (-> x meta ::datafy) -datafy) x)]
22+
(if (identical? v x)
23+
v
24+
(if (object? v)
25+
(vary-meta v assoc ::obj x)
26+
v))))
27+
28+
(defn nav
29+
"Returns (possibly transformed) v in the context of coll and k (a
30+
key/index or nil). Callers should attempt to provide the key/index
31+
context k for Indexed/Associative/ILookup colls if possible, but not
32+
to fabricate one e.g. for sequences (pass nil). If :clojure.datafy/nav is
33+
present as metadata on coll, it will be called with coll, k and v as
34+
arguments, else nav will call :clojure.protocols/nav."
35+
[coll k v]
36+
((or (-> coll meta ::nav) -nav) coll k v))
37+
38+
(defn- datify-ref [r]
39+
(with-meta [(deref r)] (meta r)))
40+
41+
(extend-protocol IDatafiable
42+
Var
43+
(-datafy [r] (datify-ref r))
44+
45+
Reduced
46+
(-datafy [r] (datify-ref r))
47+
48+
Atom
49+
(-datafy [r] (datify-ref r))
50+
51+
Volatile
52+
(-datafy [r] (datify-ref r))
53+
54+
Delay
55+
(-datafy [r] (datify-ref r)))

0 commit comments

Comments
 (0)