;;;; String: owned, growable, always valid UTF-8. Multi-byte append, insert ;;;; and remove by character position, iteration by runes, the byte length ;;;; beside the character count, a copy, printing inside a structure, and a ;;;; String crossing into dyn as a copy of its text. (defstruct Named [label String n i32]) (defn as-dyn [d] dyn d) (defn main [] i32 (let [s (string-new "héllo")] (append s " wörld") (append s 0x65e5) ; 日, three bytes (append s \!) (println s) (println (length s) (rune-count s)) ;; Positions are characters: 1 is after the h, whatever é takes. (insert s 1 "→") (insert s 0 0x1f600) ; four bytes at the front (println s) (println (remove s 2)) ; the → that was inserted, as a code point (println (remove s 0)) ; the emoji (println s) ;; Appending a String to itself reads the bytes it had before growing. (let [t (string-new "ab")] (append t t) (append t t) (println t (length t)) (free t)) ;; Iteration by runes. (let [it (runes s) going true n 0] (while going (match (runes-next (addr it)) (Some c) (do (when (> c 127) (print c "")) (set n (+ n 1))) None (set going false))) (println n)) ;; A copy is independent of the original. (let [c (clone s)] (append c "?") (println (length s) (length c)) (free c)) ;; The str view and the byte view cost nothing. (println (= (str s) "héllo wörld日!")) (println (length (bytes-view s))) ;; Inside a structure it prints quoted, as a str field does. (let [m (Named {.label (string-new "x") .n 3})] (println m) (free (.label m))) ;; Crossing into dyn copies the text, which the dyn side then owns. (let [d (as-dyn s)] (append s "tail") (println d) (println (type-of d))) ;; The builders answer Strings. (let [j (join (slice [(bytes-view "a") (bytes-view "b")]) (bytes-view "-"))] (println j) (free j)) ;; = and != compare bytes, against a String or a str, either side first. (let [a (string-new "日本") b (string-new "日")] (append b 0x672c) (println (= a b) (!= a b) (= a "日本") (= "日本" a) (= a "日") (!= b "x")) (println (= a b (to-upper (bytes-view "日本")))) (free a) (free b)) ;; bytes->string copies: a write through the Vec afterwards, or through a ;; slice taken of it before, does not reach the String. (let [v (vec-new u8)] (push v 0xc3) (push v 0xa9) (let [early (slice v) t (bytes->string v)] (set (at v 0) 0xff) (set (at early 1) 0xe6) (println t (length t) (rune-count t)) (free t)) (free v)) ;; A remove near the front and an insert at the front, on a long text. (let [long (string-new "é")] (dotimes [i 1000] (append long "ab")) (insert long 0 "x") (println (remove long 1) (length long)) (free long)) (let [e (string-new)] (println (length e) (rune-count e)) (free e)) (free s)) 0)