aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/data/text/buffer.lux
blob: 6260894c6b7d8d81f480aa3dfac2f2f9c67e8e1b (plain)
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
(.module:
  [lux #*
   [data
    ["." product]
    [text
     format]
    [collection
     ["." row (#+ Row) ("#;." fold)]]]
   [compiler
    ["_" 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))))
      ))