aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--stdlib/source/lux/data/text/buffer.lux72
1 files changed, 72 insertions, 0 deletions
diff --git a/stdlib/source/lux/data/text/buffer.lux b/stdlib/source/lux/data/text/buffer.lux
new file mode 100644
index 000000000..423a1ba3c
--- /dev/null
+++ b/stdlib/source/lux/data/text/buffer.lux
@@ -0,0 +1,72 @@
+(.module:
+ lux
+ (lux (data [product]
+ text/format
+ (coll [row #+ Row "row/" Fold<Row>]))
+ (lang ["_" host])
+ (type abstract)
+ [host #+ import:])
+ [//])
+
+(`` (for {(~~ (static _.jvm))
+ (as-is (import: java/lang/CharSequence)
+
+ (import: java/lang/Appendable
+ (append [CharSequence] Appendable))
+
+ (import: java/lang/StringBuilder
+ (new [int])
+ (toString [] String)))}))
+
+(`` (abstract: #export Buffer
+ {#.doc "Immutable text buffer for efficient text concatenation."}
+
+ (for {(~~ (static _.jvm))
+ [Nat (-> StringBuilder StringBuilder)]}
+ ## default
+ (Row Text))
+
+ (def: #export empty
+ Buffer
+ (:abstraction (for {(~~ (static _.jvm))
+ [+0 id]}
+ ## default
+ row.empty)))
+
+ (def: #export (append chunk buffer)
+ (-> Text Buffer Buffer)
+ (for {(~~ (static _.jvm))
+ (let [[capacity transform] (:representation buffer)
+ append! (: (-> Text StringBuilder StringBuilder)
+ (function (_ chunk builder)
+ (exec (Appendable::append [(:coerce CharSequence chunk)]
+ builder)
+ builder)))]
+ (:abstraction [(n/+ (//.size chunk) capacity)
+ (|>> transform (append! chunk))]))}
+ ## default
+ (|> buffer :representation (row.add chunk) :abstraction)))
+
+ (def: #export (size buffer)
+ (-> Buffer Nat)
+ (for {(~~ (static _.jvm))
+ (|> buffer :representation product.left)}
+ ## default
+ (row/fold (function (_ chunk total)
+ (n/+ (//.size chunk) total))
+ +0
+ (:representation buffer))))
+
+ (def: #export (text buffer)
+ (-> Buffer Text)
+ (for {(~~ (static _.jvm))
+ (let [[capacity transform] (:representation buffer)]
+ (|> (StringBuilder::new [(.int capacity)])
+ transform
+ (StringBuilder::toString [])))}
+ ## default
+ (row/fold (function (_ chunk total)
+ (format total chunk))
+ ""
+ (:representation buffer))))
+ ))