aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/data/text/buffer.lux
blob: e4ebba1c9741c6335a8e60af7ee11d43ad935de5 (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
84
85
86
87
88
89
90
91
92
93
94
(.module:
  [lux #*
   [host (#+ import:)]
   ["@" target]
   [control
    ["." function]]
   [data
    ["." product]
    [text
     ["%" format (#+ format)]]
    [collection
     ["." row (#+ Row) ("#\." fold)]]]
   [math
    [number
     ["n" nat]]]
   [type
    abstract]]
  ["." //])

(with_expansions [<jvm> (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)]))]
  (`` (for {@.old (as_is <jvm>)
            @.jvm (as_is <jvm>)}
           (as_is))))

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

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

      (def: #export empty
        Buffer
        (:abstraction (with_expansions [<jvm> [0 function.identity]]
                        (for {@.old <jvm>
                              @.jvm <jvm>}
                             ## default
                             row.empty))))

      (def: #export (append chunk buffer)
        (-> Text Buffer Buffer)
        (with_expansions [<jvm> (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))]))]
          (for {@.old <jvm>
                @.jvm <jvm>}
               ## default
               (|> buffer :representation (row.add chunk) :abstraction))))

      (def: #export size
        (-> Buffer Nat)
        (with_expansions [<jvm> (|>> :representation product.left)]
          (for {@.old <jvm>
                @.jvm <jvm>}
               ## default
               (|>> :representation
                    (row\fold (function (_ chunk total)
                                (n.+ (//.size chunk) total))
                              0)))))

      (def: #export (text buffer)
        (-> Buffer Text)
        (with_expansions [<jvm> (let [[capacity transform] (:representation buffer)]
                                  (|> (java/lang/StringBuilder::new (.int capacity))
                                      transform
                                      java/lang/StringBuilder::toString))]
          (for {@.old <jvm>
                @.jvm <jvm>}
               ## default
               (row\fold (function (_ chunk total)
                           (format total chunk))
                         ""
                         (:representation buffer)))))
      ))