aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/data/text/buffer.lux
blob: 24416ea0df5c387f23f3b231699ee37beed00a14 (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
78
79
80
81
82
83
(.module:
  [lux #*
   [host (#+ import:)]
   [data
    ["." product]
    [number
     ["n" nat]]
    [text
     ["%" format (#+ format)]]
    [collection
     ["." row (#+ Row) ("#@." fold)]]]
   [compiler
    ["_" host]]
   [type
    abstract]]
  ["." //])

(`` (for {(~~ (static _.old))
          (as-is (import: java/lang/CharSequence)

                 (import: java/lang/Appendable
                   (append [java/lang/CharSequence] java/lang/Appendable))

                 (import: java/lang/String
                   (new [int])
                   (toString [] java/lang/String))

                 (import: java/lang/StringBuilder
                   (new [int])
                   (toString [] java/lang/String)))}))

(`` (abstract: #export Buffer
      (for {(~~ (static _.old))
            [Nat (-> java/lang/StringBuilder java/lang/StringBuilder)]}
           ## default
           (Row Text))

      {#.doc "Immutable text buffer for efficient text concatenation."}

      (def: #export empty
        Buffer
        (:abstraction (for {(~~ (static _.old))
                            [0 id]}
                           ## default
                           row.empty)))

      (def: #export (append chunk buffer)
        (-> Text Buffer Buffer)
        (for {(~~ (static _.old))
              (let [[capacity transform] (:representation buffer)
                    append! (: (-> Text java/lang/StringBuilder java/lang/StringBuilder)
                               (function (_ chunk builder)
                                 (exec (java/lang/Appendable::append (:coerce java/lang/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 _.old))
              (|> 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 _.old))
              (let [[capacity transform] (:representation buffer)]
                (|> (java/lang/StringBuilder::new (.int capacity))
                    transform
                    java/lang/StringBuilder::toString))}
             ## default
             (row@fold (function (_ chunk total)
                         (format total chunk))
                       ""
                       (:representation buffer))))
      ))