Skip to content

Commit 1c9cde3

Browse files
authored
Add startsWith and endsWith (#147)
1 parent 03b03a7 commit 1c9cde3

File tree

7 files changed

+85
-5
lines changed

7 files changed

+85
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Notable changes to this project are documented in this file. The format is based
77
Breaking changes:
88

99
New features:
10+
- Added `startsWith` and `endsWith` (#147)
1011

1112
Bugfixes:
1213

src/Data/String/CodePoints.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import Data.Array as Array
3434
import Data.Enum (class BoundedEnum, class Enum, Cardinality(..), defaultPred, defaultSucc, fromEnum, toEnum, toEnumWithDefaults)
3535
import Data.Int (hexadecimal, toStringAs)
3636
import Data.Maybe (Maybe(..))
37-
import Data.String.CodeUnits (contains, stripPrefix, stripSuffix) as Exports
37+
import Data.String.CodeUnits (contains, stripPrefix, stripSuffix, startsWith, endsWith) as Exports
3838
import Data.String.CodeUnits as CU
3939
import Data.String.Common (toUpper)
4040
import Data.String.Pattern (Pattern)

src/Data/String/CodeUnits.purs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ module Data.String.CodeUnits
2222
, dropWhile
2323
, slice
2424
, splitAt
25+
, startsWith
26+
, endsWith
2527
) where
2628

2729
import Prelude
@@ -31,9 +33,10 @@ import Data.String.Pattern (Pattern(..))
3133
import Data.String.Unsafe as U
3234

3335
-------------------------------------------------------------------------------
34-
-- `stripPrefix`, `stripSuffix`, and `contains` are CodeUnit/CodePoint agnostic
35-
-- as they are based on patterns rather than lengths/indices, but they need to
36-
-- be defined in here to avoid a circular module dependency
36+
-- `stripPrefix`, `stripSuffix`, `startsWith`, `endsWith`, and `contains` are
37+
-- CodeUnit/CodePoint agnostic as they are based on patterns rather than
38+
-- lengths/indices, but they need to be defined in here to avoid a circular
39+
-- module dependency
3740
-------------------------------------------------------------------------------
3841

3942
-- | If the string starts with the given prefix, return the portion of the
@@ -61,6 +64,30 @@ stripSuffix (Pattern suffix) str =
6164
let { before, after } = splitAt (length str - length suffix) str in
6265
if after == suffix then Just before else Nothing
6366

67+
-- | Checks whether the given string starts with the pattern.
68+
-- |
69+
-- | **NOTE**: if you also want to get the string stripped of the pattern, see
70+
-- | `stripPrefix`.
71+
-- |
72+
-- | ```purescript
73+
-- | startsWith (Pattern "foo") "foobar" == true
74+
-- | startsWith (Pattern "bar") "foobar" == false
75+
-- | ```
76+
startsWith :: Pattern -> String -> Boolean
77+
startsWith pat = isJust <<< stripPrefix pat
78+
79+
-- | Checks whether the given string ends with the pattern.
80+
-- |
81+
-- | **NOTE**: if you also want to get the string stripped of the pattern, see
82+
-- | `stripSuffix`.
83+
-- |
84+
-- | ```purescript
85+
-- | endsWith (Pattern "bar") "foobar" == true
86+
-- | endsWith (Pattern "foo") "foobar" == false
87+
-- | ```
88+
endsWith :: Pattern -> String -> Boolean
89+
endsWith pat = isJust <<< stripSuffix pat
90+
6491
-- | Checks whether the pattern appears in the given string.
6592
-- |
6693
-- | ```purescript

src/Data/String/NonEmpty.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ module Data.String.NonEmpty
44
, module Data.String.NonEmpty.CodePoints
55
) where
66

7-
import Data.String.NonEmpty.Internal (NonEmptyString, class MakeNonEmpty, NonEmptyReplacement(..), appendString, contains, fromString, join1With, joinWith, joinWith1, localeCompare, nes, prependString, replace, replaceAll, stripPrefix, stripSuffix, toLower, toString, toUpper, trim, unsafeFromString)
7+
import Data.String.NonEmpty.Internal (NonEmptyString, class MakeNonEmpty, NonEmptyReplacement(..), appendString, contains, fromString, join1With, joinWith, joinWith1, localeCompare, nes, prependString, replace, replaceAll, stripPrefix, stripSuffix, startsWith, endsWith, toLower, toString, toUpper, trim, unsafeFromString)
88
import Data.String.Pattern (Pattern(..))
99
import Data.String.NonEmpty.CodePoints

src/Data/String/NonEmpty/Internal.purs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,31 @@ stripPrefix pat = fromString <=< liftS (String.stripPrefix pat)
124124
stripSuffix :: Pattern -> NonEmptyString -> Maybe NonEmptyString
125125
stripSuffix pat = fromString <=< liftS (String.stripSuffix pat)
126126

127+
128+
-- | Checks whether the given string starts with the pattern.
129+
-- |
130+
-- | **NOTE**: if you also want to get the string stripped of the pattern, see
131+
-- | `stripPrefix`.
132+
-- |
133+
-- | ```purescript
134+
-- | startsWith (Pattern "foo") (NonEmptyString "foobar") == true
135+
-- | startsWith (Pattern "bar") (NonEmptyString "foobar") == false
136+
-- | ```
137+
startsWith :: Pattern -> NonEmptyString -> Boolean
138+
startsWith = liftS <<< String.startsWith
139+
140+
-- | Checks whether the given string ends with the pattern.
141+
-- |
142+
-- | **NOTE**: if you also want to get the string stripped of the pattern, see
143+
-- | `stripSuffix`.
144+
-- |
145+
-- | ```purescript
146+
-- | endsWith (Pattern "bar") (NonEmptyString "foobar") == true
147+
-- | endsWith (Pattern "foo") (NonEmptyString "foobar") == false
148+
-- | ```
149+
endsWith :: Pattern -> NonEmptyString -> Boolean
150+
endsWith = liftS <<< String.endsWith
151+
127152
-- | Checks whether the pattern appears in the given string.
128153
-- |
129154
-- | ```purescript

test/Test/Data/String/CodeUnits.purs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@ testStringCodeUnits = do
6464
, expected: Just ""
6565
}
6666

67+
log "startsWith"
68+
assert $ SCU.startsWith (Pattern "foo") "foobar"
69+
assert $ SCU.startsWith (Pattern "foo") "foo"
70+
assert $ SCU.startsWith (Pattern "") ""
71+
assert $ SCU.startsWith (Pattern "") "foo"
72+
assert $ not $ SCU.startsWith (Pattern "foo") ""
73+
74+
log "endsWith"
75+
assert $ SCU.endsWith (Pattern "bar") "foobar"
76+
assert $ SCU.endsWith (Pattern "bar") "bar"
77+
assert $ SCU.endsWith (Pattern "") ""
78+
assert $ SCU.endsWith (Pattern "") "bar"
79+
assert $ not $ SCU.endsWith (Pattern "bar") ""
80+
6781
log "charAt"
6882
assertEqual
6983
{ actual: SCU.charAt 0 ""

test/Test/Data/String/NonEmpty.purs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,19 @@ testNonEmptyString = do
144144
, expected: Nothing
145145
}
146146

147+
log "startsWith"
148+
assert $ NES.startsWith (Pattern "foo") (nes (Proxy :: Proxy "foobar"))
149+
assert $ NES.startsWith (Pattern "foo") (nes (Proxy :: Proxy "foo"))
150+
assert $ NES.startsWith (Pattern "") (nes (Proxy :: Proxy "foo"))
151+
assert $ not $ NES.startsWith (Pattern "foo") (nes (Proxy :: Proxy "f"))
152+
153+
log "endsWith"
154+
assert $ NES.endsWith (Pattern "bar") (nes (Proxy :: Proxy "foobar"))
155+
assert $ NES.endsWith (Pattern "bar") (nes (Proxy :: Proxy "bar"))
156+
assert $ NES.endsWith (Pattern "") (nes (Proxy :: Proxy "f"))
157+
assert $ NES.endsWith (Pattern "") (nes (Proxy :: Proxy "bar"))
158+
assert $ not $ NES.endsWith (Pattern "bar") (nes (Proxy :: Proxy "b"))
159+
147160
log "toLower"
148161
assertEqual
149162
{ actual: NES.toLower (nes (Proxy :: Proxy "bAtMaN"))

0 commit comments

Comments
 (0)