From 30ff8f75eca8eb230f034172daf777be50332553 Mon Sep 17 00:00:00 2001 From: Jon Pretty Date: Tue, 22 Oct 2024 16:24:32 +0200 Subject: [PATCH] Use `Segmentable` --- src/core/gossamer-core.scala | 32 +++++++++++--------------- src/core/gossamer.Cuttable.scala | 6 ++--- src/core/gossamer.Presentational.scala | 2 +- src/core/gossamer.Textual.scala | 4 ++-- src/core/soundness+gossamer-core.scala | 2 +- 5 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/core/gossamer-core.scala b/src/core/gossamer-core.scala index 45bf370..99a0e27 100644 --- a/src/core/gossamer-core.scala +++ b/src/core/gossamer-core.scala @@ -113,7 +113,7 @@ extension [TextType: Textual](text: TextType) if !predicate(TextType.unsafeChar(text, index - 1), TextType.unsafeChar(text, index)) then recur(from, index + 1) else - buffer.append(text.slice(from ~ index.previous)) + buffer.append(text.segment(from ~ index.previous)) buffer.append(breakText) recur(index, index + 1) @@ -131,18 +131,18 @@ extension [TextType: Textual](text: TextType) recur(Prim, extra, words(0)) - def before(ordinal: Ordinal): TextType = text.slice(Prim ~ (ordinal - 1)) - def after(ordinal: Ordinal): TextType = text.slice((ordinal + 1) ~ Ult.of(text)) - def upto(ordinal: Ordinal): TextType = text.slice(Prim ~ ordinal) - def from(ordinal: Ordinal): TextType = text.slice(ordinal ~ Ult.of(text)) + def before(ordinal: Ordinal): TextType = text.segment(Prim ~ (ordinal - 1)) + def after(ordinal: Ordinal): TextType = text.segment((ordinal + 1) ~ Ult.of(text)) + def upto(ordinal: Ordinal): TextType = text.segment(Prim ~ ordinal) + def from(ordinal: Ordinal): TextType = text.segment(ordinal ~ Ult.of(text)) def skip(count: Int, bidi: Bidi = Ltr): TextType = bidi match - case Ltr => text.slice(Ordinal.zerary(count) ~ Ult.of(text)) - case Rtl => text.slice(Prim ~ Countback(count).of(text)) + case Ltr => text.segment(Ordinal.zerary(count) ~ Ult.of(text)) + case Rtl => text.segment(Prim ~ Countback(count).of(text)) def keep(count: Int, bidi: Bidi = Ltr): TextType = bidi match - case Ltr => text.slice(Interval.initial(count)) - case Rtl => text.slice(Countback(count - 1).of(text) ~ Ult.of(text)) + case Ltr => text.segment(Interval.initial(count)) + case Rtl => text.segment(Countback(count - 1).of(text) ~ Ult.of(text)) def capitalize: TextType = TextType.concat(text.keep(1).upper, text.after(Prim)) def uncapitalize: TextType = TextType.concat(text.keep(1).lower, text.after(Prim)) @@ -153,21 +153,18 @@ extension [TextType: Textual](text: TextType) def chars: IArray[Char] = TextType.text(text).s.toCharArray.nn.immutable(using Unsafe) - def slice(interval: Interval): TextType = - if interval.end <= interval.start then TextType.empty else TextType.range(text, interval) - def snip(n: Int): (TextType, TextType) = - (text.slice(Prim ~ Ordinal.zerary(n - 1)), text.slice(Ordinal.zerary(n) ~ Ult.of(text))) + (text.segment(Prim ~ Ordinal.zerary(n - 1)), text.segment(Ordinal.zerary(n) ~ Ult.of(text))) def punch(n: Ordinal): (TextType, TextType) = - (text.slice(Prim ~ (n - 1)), text.slice((n + 1) ~ Ult.of(text))) + (text.segment(Prim ~ (n - 1)), text.segment((n + 1) ~ Ult.of(text))) // def char(index: Ordinal): Optional[Char] = // if index >= Prim && index <= Ult.of(text) then TextType.unsafeChar(text, index) else Unset inline def reverse: TextType = def recur(index: Ordinal, result: TextType): TextType = - if index <= Ult.of(text) then recur(index + 1, TextType.concat(text.slice(index ~ index), result)) + if index <= Ult.of(text) then recur(index + 1, TextType.concat(text.segment(index ~ index), result)) else result recur(Prim, TextType.empty) @@ -179,7 +176,7 @@ extension [TextType: Textual](text: TextType) inline def trim: TextType = val start = text.where(!_.isWhitespace).or(Ult.of(text)) val end = text.where(!_.isWhitespace, bidi = Rtl).or(Prim) - text.slice(start ~ end) + text.segment(start ~ end) def where(pred: Char => Boolean, start: Optional[Ordinal] = Unset, bidi: Bidi = Ltr) : Optional[Ordinal] = @@ -208,7 +205,7 @@ extension [TextType: Textual](text: TextType) def dropWhile(pred: Char => Boolean): TextType = text.where(!pred(_)).lay(TextType.empty): ordinal => - text.slice(ordinal ~ Ult.of(text)) + text.segment(ordinal ~ Ult.of(text)) def whilst(pred: Char => Boolean): TextType = text.where(!pred(_)).lay(TextType.empty): ordinal => @@ -390,4 +387,3 @@ package enumIdentification: given [EnumType <: reflect.Enum] => EnumType is Identifiable as camelCase = Identifiable(_.uncamel.camel, _.unsnake.pascal) - diff --git a/src/core/gossamer.Cuttable.scala b/src/core/gossamer.Cuttable.scala index fb6fb9d..ccb03e5 100644 --- a/src/core/gossamer.Cuttable.scala +++ b/src/core/gossamer.Cuttable.scala @@ -38,8 +38,8 @@ object Cuttable: @tailrec def recur(start: Ordinal, results: List[TextType]): List[TextType] = - TextType.indexOf(text, delimiter, start).lay(text.slice(start ~ Ult.of(text)) :: results): - index => recur(index + dLength, text.slice(start ~ (index - 1)) :: results) + TextType.indexOf(text, delimiter, start).lay(text.segment(start ~ Ult.of(text)) :: results): + index => recur(index + dLength, text.segment(start ~ (index - 1)) :: results) recur(Prim, Nil).reverse @@ -52,7 +52,7 @@ object Cuttable: if matcher.find(start.n0) then val interval = Ordinal.zerary(matcher.start) ~ Ordinal.zerary(matcher.end) - recur(Ordinal.zerary(matcher.end), text.slice(interval) :: results) + recur(Ordinal.zerary(matcher.end), text.segment(interval) :: results) else results recur(Prim, Nil).reverse diff --git a/src/core/gossamer.Presentational.scala b/src/core/gossamer.Presentational.scala index 02e29cc..2a2c274 100644 --- a/src/core/gossamer.Presentational.scala +++ b/src/core/gossamer.Presentational.scala @@ -33,7 +33,7 @@ object Presentational: def apply(text: Text): Text = text def map(text: Text, lambda: Char => Char): Text = Text(text.s.map(lambda)) - def range(text: Text, interval: Interval): Text = + def segment(text: Text, interval: Interval): Text = val limit = length(text) val start = interval.start.n0.max(0).min(limit) val end = interval.end.n0.max(start).min(limit) diff --git a/src/core/gossamer.Textual.scala b/src/core/gossamer.Textual.scala index 3a2d846..1f26dd1 100644 --- a/src/core/gossamer.Textual.scala +++ b/src/core/gossamer.Textual.scala @@ -23,18 +23,18 @@ import denominative.* import language.experimental.captureChecking -trait Textual extends Presentational, Countable: +trait Textual extends Presentational, Countable, Segmentable: type Self def classTag: ClassTag[Self] def length(text: Self): Int def text(text: Self): Text def map(text: Self, lambda: Char => Char): Self - def range(text: Self, interval: Interval): Self def empty: Self def concat(left: Self, right: Self): Self def unsafeChar(text: Self, index: Ordinal): Char def indexOf(text: Self, sub: Text, start: Ordinal = Prim): Optional[Ordinal] def buffer(size: Optional[Int] = Unset): Buffer[Self] + def segment(text: Self, interval: Interval): Self extension (left: Self) @targetName("mul") diff --git a/src/core/soundness+gossamer-core.scala b/src/core/soundness+gossamer-core.scala index 032386a..9066c6f 100644 --- a/src/core/soundness+gossamer-core.scala +++ b/src/core/soundness+gossamer-core.scala @@ -20,7 +20,7 @@ export gossamer.{Bidi, Buffer, Cuttable, Decimalizer, Interpolation, Joinable, N Presentational, Pue, RangeError, TextBuffer, Textual, append, construct, fill, txt, t, utf8, utf16, ascii, hex, text, pue, cut, pascal, camel, snake, kebab, length, populated, lower, upper, plain, skip, keep, capitalize, uncapitalize, tail, init, empty, chars, - slice, snip, reverse, contains, trim, where, upto, dropWhile, snipWhere, + snip, reverse, contains, trim, where, upto, dropWhile, snipWhere, mapChars, count, metrics, pad, center, fit, uncamel, unkebab, unsnake, starts, ends, tr, subscript, superscript, rsub, sub, flatMap, urlEncode, urlDecode, punycode, bytes, sysBytes, lev, join, add, words, lines, appendln}