Permalink
Browse files

Add an io package.

Can create pushback readers, and read a seq of forms from a reader.
  • Loading branch information...
1 parent 8eb5ce9 commit 479a49b2b356400f2fc62e5dd2e73be358b60efb @amalloy amalloy committed Nov 14, 2011
Showing with 37 additions and 1 deletion.
  1. +1 −1 src/useful/core.clj
  2. +28 −0 src/useful/io.clj
  3. +8 −0 test/useful/io_test.clj
View
@@ -1,5 +1,5 @@
(ns useful.core
(:use [useful.ns :only [alias-ns]]))
-(doseq [module '(bean cli compress datatypes debug dispatch experimental experimental.unicode fn java macro map parallel seq state string test utils)]
+(doseq [module '(bean cli compress datatypes debug dispatch experimental experimental.unicode fn io java macro map parallel seq state string test utils)]
(alias-ns (symbol (str "useful." module))))
View
@@ -0,0 +1,28 @@
+(ns useful.io
+ (:use [clojure.java.io :only [reader]])
+ (:import (java.io Reader PushbackReader)))
+
+(defprotocol PushbackFactory
+ (^{:added "1.4"} pushback-reader [x] "Creates a PushbackReader from an object."))
+
+(extend-protocol PushbackFactory
+ PushbackReader
+ (pushback-reader [this]
+ this)
+
+ Reader
+ (pushback-reader [this]
+ (PushbackReader. this))
+
+ Object
+ (pushback-reader [this]
+ (pushback-reader (reader this))))
+
+(let [sentinel (Object.)
+ valid? #(not (identical? % sentinel))]
+ (defn read-seq
+ "Read a lazy sequence of Clojure forms from an input reader."
+ [in]
+ (let [in (pushback-reader in)]
+ (take-while valid?
+ (repeatedly #(read in false sentinel))))))
View
@@ -0,0 +1,8 @@
+(ns useful.io-test
+ (:use useful.io clojure.test))
+
+(deftest test-read-seq
+ (let [forms '(this (is) #(100 %) ~of a [long, [complicated, [nested]]] {:quoted #{form}})
+ form-str (with-out-str (doseq [form forms]
+ (prn form)))]
+ (is (= forms (read-seq (java.io.StringReader. form-str))))))

0 comments on commit 479a49b

Please sign in to comment.