From 36493eee748bc35e2d4ecb09992f3c3eae42f4e8 Mon Sep 17 00:00:00 2001 From: Mohammed Anas <6daf084a-8eaf-40fb-86c7-8500077c3b69@anonaddy.me> Date: Thu, 22 Apr 2021 19:26:30 +0000 Subject: [PATCH 01/14] Use backticks around PS code in docs (#148) * Use backticks around PS code in docs * Add change to CHANGELOG.md --- CHANGELOG.md | 1 + src/Data/String/CodePoints.purs | 14 +++++++------- src/Data/String/CodeUnits.purs | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 311b72b..c3bf386 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ New features: Bugfixes: Other improvements: +- Surround code with backticks in documentation (#148) ## [v5.0.0](https://github.com/purescript/purescript-strings/releases/tag/v5.0.0) - 2021-02-26 diff --git a/src/Data/String/CodePoints.purs b/src/Data/String/CodePoints.purs index 7d0f528..65e0b55 100644 --- a/src/Data/String/CodePoints.purs +++ b/src/Data/String/CodePoints.purs @@ -42,7 +42,7 @@ import Data.String.Unsafe as Unsafe import Data.Tuple (Tuple(..)) import Data.Unfoldable (unfoldr) --- | CodePoint is an Int bounded between 0 and 0x10FFFF, corresponding to +-- | CodePoint is an `Int` bounded between `0` and `0x10FFFF`, corresponding to -- | Unicode code points. newtype CodePoint = CodePoint Int @@ -67,7 +67,7 @@ instance boundedEnumCodePoint :: BoundedEnum CodePoint where | n >= 0 && n <= 0x10FFFF = Just (CodePoint n) | otherwise = Nothing --- | Creates a CodePoint from a given Char. +-- | Creates a `CodePoint` from a given `Char`. -- | -- | ```purescript -- | >>> codePointFromChar 'B' @@ -178,7 +178,7 @@ codePointAtFallback n s = case uncons s of _ -> Nothing -- | Returns a record with the first code point and the remaining code points --- | of the string. Returns Nothing if the string is empty. Operates in +-- | of the string. Returns `Nothing` if the string is empty. Operates in -- | constant space and time. -- | -- | ```purescript @@ -243,7 +243,7 @@ countTail p s accum = case uncons s of _ -> accum -- | Returns the number of code points preceding the first match of the given --- | pattern in the string. Returns Nothing when no matches are found. +-- | pattern in the string. Returns `Nothing` when no matches are found. -- | -- | ```purescript -- | >>> indexOf (Pattern "𝐀") "b 𝐀𝐀 c 𝐀" @@ -257,7 +257,7 @@ indexOf p s = (\i -> length (CU.take i s)) <$> CU.indexOf p s -- | Returns the number of code points preceding the first match of the given -- | pattern in the string. Pattern matches preceding the given index will be --- | ignored. Returns Nothing when no matches are found. +-- | ignored. Returns `Nothing` when no matches are found. -- | -- | ```purescript -- | >>> indexOf' (Pattern "𝐀") 4 "b 𝐀𝐀 c 𝐀" @@ -272,7 +272,7 @@ indexOf' p i s = (\k -> i + length (CU.take k s')) <$> CU.indexOf p s' -- | Returns the number of code points preceding the last match of the given --- | pattern in the string. Returns Nothing when no matches are found. +-- | pattern in the string. Returns `Nothing` when no matches are found. -- | -- | ```purescript -- | >>> lastIndexOf (Pattern "𝐀") "b 𝐀𝐀 c 𝐀" @@ -292,7 +292,7 @@ lastIndexOf p s = (\i -> length (CU.take i s)) <$> CU.lastIndexOf p s -- | greater than the number of code points in the string is equivalent to -- | searching in the whole string. -- | --- | Returns Nothing when no matches are found. +-- | Returns `Nothing` when no matches are found. -- | -- | ```purescript -- | >>> lastIndexOf' (Pattern "𝐀") (-1) "b 𝐀𝐀 c 𝐀" diff --git a/src/Data/String/CodeUnits.purs b/src/Data/String/CodeUnits.purs index dfa0482..fbc1803 100644 --- a/src/Data/String/CodeUnits.purs +++ b/src/Data/String/CodeUnits.purs @@ -37,7 +37,7 @@ import Data.String.Unsafe as U ------------------------------------------------------------------------------- -- | If the string starts with the given prefix, return the portion of the --- | string left after removing it, as a Just value. Otherwise, return Nothing. +-- | string left after removing it, as a `Just` value. Otherwise, return `Nothing`. -- | -- | ```purescript -- | stripPrefix (Pattern "http:") "http://purescript.org" == Just "//purescript.org" From a8e757faa17ff24e6add938ba61a9375c867dd40 Mon Sep 17 00:00:00 2001 From: JordanMartinez Date: Tue, 15 Mar 2022 13:18:54 -0700 Subject: [PATCH 02/14] Update to v0.15.0 (#158) * Convert foreign modules to try bundling with esbuild * Replaced 'export var' with 'export const' * Removed '"use strict";' in FFI files * Update to CI to use 'unstable' purescript * Update pulp to 16.0.0-0 and psa to 0.8.2 * Update Bower dependencies to master * Update .eslintrc.json to ES6 * Fix compiler error due to Proxy type * Fix unused name compiler warnings * Added changelog entry * Update test script to use import Co-authored-by: Cyril Sobierajewicz --- .eslintrc.json | 6 +-- .github/workflows/ci.yml | 2 + CHANGELOG.md | 2 + bower.json | 38 +++++++++---------- package.json | 6 +-- src/Data/String/CodePoints.js | 15 ++++---- src/Data/String/CodeUnits.js | 32 ++++++++-------- src/Data/String/Common.js | 18 ++++----- src/Data/String/NonEmpty/Internal.purs | 3 +- src/Data/String/Regex.js | 22 +++++------ src/Data/String/Unsafe.js | 6 +-- test/Test/Data/String/NonEmpty/CodeUnits.purs | 8 ++-- 12 files changed, 76 insertions(+), 82 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 84cef4f..1c6afb9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,11 +1,9 @@ { "parserOptions": { - "ecmaVersion": 5 + "ecmaVersion": 6, + "sourceType": "module" }, "extends": "eslint:recommended", - "env": { - "commonjs": true - }, "rules": { "strict": [2, "global"], "block-scoped-var": 2, diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 43d2897..b6ebf3a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,8 @@ jobs: - uses: actions/checkout@v2 - uses: purescript-contrib/setup-purescript@main + with: + purescript: "unstable" - uses: actions/setup-node@v1 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index c3bf386..d63cbd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ Notable changes to this project are documented in this file. The format is based ## [Unreleased] Breaking changes: +- Migrate FFI to ES modules (#158 by @kl0tl and @JordanMartinez) +- Replaced polymorphic proxies with monomorphic `Proxy` (#158 by @JordanMartinez) New features: diff --git a/bower.json b/bower.json index d4c9f36..2b8dd58 100644 --- a/bower.json +++ b/bower.json @@ -16,26 +16,26 @@ "package.json" ], "dependencies": { - "purescript-arrays": "^6.0.0", - "purescript-control": "^5.0.0", - "purescript-either": "^5.0.0", - "purescript-enums": "^5.0.0", - "purescript-foldable-traversable": "^5.0.0", - "purescript-gen": "^3.0.0", - "purescript-integers": "^5.0.0", - "purescript-maybe": "^5.0.0", - "purescript-newtype": "^4.0.0", - "purescript-nonempty": "^6.0.0", - "purescript-partial": "^3.0.0", - "purescript-prelude": "^5.0.0", - "purescript-tailrec": "^5.0.0", - "purescript-tuples": "^6.0.0", - "purescript-unfoldable": "^5.0.0", - "purescript-unsafe-coerce": "^5.0.0" + "purescript-arrays": "master", + "purescript-control": "master", + "purescript-either": "master", + "purescript-enums": "master", + "purescript-foldable-traversable": "master", + "purescript-gen": "master", + "purescript-integers": "master", + "purescript-maybe": "master", + "purescript-newtype": "master", + "purescript-nonempty": "master", + "purescript-partial": "master", + "purescript-prelude": "master", + "purescript-tailrec": "master", + "purescript-tuples": "master", + "purescript-unfoldable": "master", + "purescript-unsafe-coerce": "master" }, "devDependencies": { - "purescript-assert": "^5.0.0", - "purescript-console": "^5.0.0", - "purescript-minibench": "^3.0.0" + "purescript-assert": "master", + "purescript-console": "master", + "purescript-minibench": "master" } } diff --git a/package.json b/package.json index c116cae..cffd45e 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,15 @@ "clean": "rimraf output && rimraf .pulp-cache", "build": "eslint src && pulp build -- --censor-lib --strict", "test": "pulp test && npm run test:run:without_codePointAt", - "test:run:without_codePointAt": "node -e \"delete String.prototype.codePointAt; require('./output/Test.Main/index.js').main();\"", + "test:run:without_codePointAt": "node -e \"delete String.prototype.codePointAt; import('./output/Test.Main/index.js').then(m => m.main());\"", "bench:build": "purs compile 'bench/**/*.purs' 'src/**/*.purs' 'bower_components/*/src/**/*.purs'", "bench:run": "node --expose-gc -e 'require(\"./output/Bench.Main/index.js\").main()'", "bench": "npm run bench:build && npm run bench:run" }, "devDependencies": { "eslint": "^7.15.0", - "pulp": "^15.0.0", - "purescript-psa": "^0.8.0", + "pulp": "16.0.0-0", + "purescript-psa": "^0.8.2", "rimraf": "^3.0.2" } } diff --git a/src/Data/String/CodePoints.js b/src/Data/String/CodePoints.js index eead7f6..ebd9e39 100644 --- a/src/Data/String/CodePoints.js +++ b/src/Data/String/CodePoints.js @@ -1,4 +1,3 @@ -"use strict"; /* global Symbol */ var hasArrayFrom = typeof Array.from === "function"; @@ -10,13 +9,13 @@ var hasStringIterator = var hasFromCodePoint = typeof String.prototype.fromCodePoint === "function"; var hasCodePointAt = typeof String.prototype.codePointAt === "function"; -exports._unsafeCodePointAt0 = function (fallback) { +export const _unsafeCodePointAt0 = function (fallback) { return hasCodePointAt ? function (str) { return str.codePointAt(0); } : fallback; }; -exports._codePointAt = function (fallback) { +export const _codePointAt = function (fallback) { return function (Just) { return function (Nothing) { return function (unsafeCodePointAt0) { @@ -40,7 +39,7 @@ exports._codePointAt = function (fallback) { }; }; -exports._countPrefix = function (fallback) { +export const _countPrefix = function (fallback) { return function (unsafeCodePointAt0) { if (hasStringIterator) { return function (pred) { @@ -59,7 +58,7 @@ exports._countPrefix = function (fallback) { }; }; -exports._fromCodePointArray = function (singleton) { +export const _fromCodePointArray = function (singleton) { return hasFromCodePoint ? function (cps) { // Function.prototype.apply will fail for very large second parameters, @@ -74,11 +73,11 @@ exports._fromCodePointArray = function (singleton) { }; }; -exports._singleton = function (fallback) { +export const _singleton = function (fallback) { return hasFromCodePoint ? String.fromCodePoint : fallback; }; -exports._take = function (fallback) { +export const _take = function (fallback) { return function (n) { if (hasStringIterator) { return function (str) { @@ -96,7 +95,7 @@ exports._take = function (fallback) { }; }; -exports._toCodePointArray = function (fallback) { +export const _toCodePointArray = function (fallback) { return function (unsafeCodePointAt0) { if (hasArrayFrom) { return function (str) { diff --git a/src/Data/String/CodeUnits.js b/src/Data/String/CodeUnits.js index 6017fd3..47d61f9 100644 --- a/src/Data/String/CodeUnits.js +++ b/src/Data/String/CodeUnits.js @@ -1,18 +1,16 @@ -"use strict"; - -exports.fromCharArray = function (a) { +export const fromCharArray = function (a) { return a.join(""); }; -exports.toCharArray = function (s) { +export const toCharArray = function (s) { return s.split(""); }; -exports.singleton = function (c) { +export const singleton = function (c) { return c; }; -exports._charAt = function (just) { +export const _charAt = function (just) { return function (nothing) { return function (i) { return function (s) { @@ -22,7 +20,7 @@ exports._charAt = function (just) { }; }; -exports._toChar = function (just) { +export const _toChar = function (just) { return function (nothing) { return function (s) { return s.length === 1 ? just(s) : nothing; @@ -30,11 +28,11 @@ exports._toChar = function (just) { }; }; -exports.length = function (s) { +export const length = function (s) { return s.length; }; -exports.countPrefix = function (p) { +export const countPrefix = function (p) { return function (s) { var i = 0; while (i < s.length && p(s.charAt(i))) i++; @@ -42,7 +40,7 @@ exports.countPrefix = function (p) { }; }; -exports._indexOf = function (just) { +export const _indexOf = function (just) { return function (nothing) { return function (x) { return function (s) { @@ -53,7 +51,7 @@ exports._indexOf = function (just) { }; }; -exports._indexOfStartingAt = function (just) { +export const _indexOfStartingAt = function (just) { return function (nothing) { return function (x) { return function (startAt) { @@ -67,7 +65,7 @@ exports._indexOfStartingAt = function (just) { }; }; -exports._lastIndexOf = function (just) { +export const _lastIndexOf = function (just) { return function (nothing) { return function (x) { return function (s) { @@ -78,7 +76,7 @@ exports._lastIndexOf = function (just) { }; }; -exports._lastIndexOfStartingAt = function (just) { +export const _lastIndexOfStartingAt = function (just) { return function (nothing) { return function (x) { return function (startAt) { @@ -91,19 +89,19 @@ exports._lastIndexOfStartingAt = function (just) { }; }; -exports.take = function (n) { +export const take = function (n) { return function (s) { return s.substr(0, n); }; }; -exports.drop = function (n) { +export const drop = function (n) { return function (s) { return s.substring(n); }; }; -exports._slice = function (b) { +export const _slice = function (b) { return function (e) { return function (s) { return s.slice(b,e); @@ -111,7 +109,7 @@ exports._slice = function (b) { }; }; -exports.splitAt = function (i) { +export const splitAt = function (i) { return function (s) { return { before: s.substring(0, i), after: s.substring(i) }; }; diff --git a/src/Data/String/Common.js b/src/Data/String/Common.js index 111c02e..5693585 100644 --- a/src/Data/String/Common.js +++ b/src/Data/String/Common.js @@ -1,6 +1,4 @@ -"use strict"; - -exports._localeCompare = function (lt) { +export const _localeCompare = function (lt) { return function (eq) { return function (gt) { return function (s1) { @@ -13,7 +11,7 @@ exports._localeCompare = function (lt) { }; }; -exports.replace = function (s1) { +export const replace = function (s1) { return function (s2) { return function (s3) { return s3.replace(s1, s2); @@ -21,7 +19,7 @@ exports.replace = function (s1) { }; }; -exports.replaceAll = function (s1) { +export const replaceAll = function (s1) { return function (s2) { return function (s3) { return s3.replace(new RegExp(s1.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"), "g"), s2); // eslint-disable-line no-useless-escape @@ -29,25 +27,25 @@ exports.replaceAll = function (s1) { }; }; -exports.split = function (sep) { +export const split = function (sep) { return function (s) { return s.split(sep); }; }; -exports.toLower = function (s) { +export const toLower = function (s) { return s.toLowerCase(); }; -exports.toUpper = function (s) { +export const toUpper = function (s) { return s.toUpperCase(); }; -exports.trim = function (s) { +export const trim = function (s) { return s.trim(); }; -exports.joinWith = function (s) { +export const joinWith = function (s) { return function (xs) { return xs.join(s); }; diff --git a/src/Data/String/NonEmpty/Internal.purs b/src/Data/String/NonEmpty/Internal.purs index 707b779..8722654 100644 --- a/src/Data/String/NonEmpty/Internal.purs +++ b/src/Data/String/NonEmpty/Internal.purs @@ -16,6 +16,7 @@ import Data.String as String import Data.String.Pattern (Pattern) import Data.Symbol (class IsSymbol, reflectSymbol) import Prim.TypeError as TE +import Type.Proxy (Proxy) import Unsafe.Coerce (unsafeCoerce) -- | A string that is known not to be empty. @@ -41,7 +42,7 @@ instance showNonEmptyString :: Show NonEmptyString where -- | something = nes (Proxy :: Proxy "something") -- | ``` class MakeNonEmpty (s :: Symbol) where - nes :: forall proxy. proxy s -> NonEmptyString + nes :: Proxy s -> NonEmptyString instance makeNonEmptyBad :: TE.Fail (TE.Text "Cannot create an NonEmptyString from an empty Symbol") => MakeNonEmpty "" where nes _ = NonEmptyString "" diff --git a/src/Data/String/Regex.js b/src/Data/String/Regex.js index b3be593..3196034 100644 --- a/src/Data/String/Regex.js +++ b/src/Data/String/Regex.js @@ -1,10 +1,8 @@ -"use strict"; - -exports.showRegexImpl = function (r) { +export const showRegexImpl = function (r) { return "" + r; }; -exports.regexImpl = function (left) { +export const regexImpl = function (left) { return function (right) { return function (s1) { return function (s2) { @@ -18,11 +16,11 @@ exports.regexImpl = function (left) { }; }; -exports.source = function (r) { +export const source = function (r) { return r.source; }; -exports.flagsImpl = function (r) { +export const flagsImpl = function (r) { return { multiline: r.multiline, ignoreCase: r.ignoreCase, @@ -33,7 +31,7 @@ exports.flagsImpl = function (r) { }; }; -exports.test = function (r) { +export const test = function (r) { return function (s) { var lastIndex = r.lastIndex; var result = r.test(s); @@ -42,7 +40,7 @@ exports.test = function (r) { }; }; -exports._match = function (just) { +export const _match = function (just) { return function (nothing) { return function (r) { return function (s) { @@ -60,7 +58,7 @@ exports._match = function (just) { }; }; -exports.replace = function (r) { +export const replace = function (r) { return function (s1) { return function (s2) { return s2.replace(r, s1); @@ -68,7 +66,7 @@ exports.replace = function (r) { }; }; -exports._replaceBy = function (just) { +export const _replaceBy = function (just) { return function (nothing) { return function (r) { return function (f) { @@ -87,7 +85,7 @@ exports._replaceBy = function (just) { }; }; -exports._search = function (just) { +export const _search = function (just) { return function (nothing) { return function (r) { return function (s) { @@ -98,7 +96,7 @@ exports._search = function (just) { }; }; -exports.split = function (r) { +export const split = function (r) { return function (s) { return s.split(r); }; diff --git a/src/Data/String/Unsafe.js b/src/Data/String/Unsafe.js index d7a17ca..75772aa 100644 --- a/src/Data/String/Unsafe.js +++ b/src/Data/String/Unsafe.js @@ -1,13 +1,11 @@ -"use strict"; - -exports.charAt = function (i) { +export const charAt = function (i) { return function (s) { if (i >= 0 && i < s.length) return s.charAt(i); throw new Error("Data.String.Unsafe.charAt: Invalid index."); }; }; -exports.char = function (s) { +export const char = function (s) { if (s.length === 1) return s.charAt(0); throw new Error("Data.String.Unsafe.char: Expected string of length 1."); }; diff --git a/test/Test/Data/String/NonEmpty/CodeUnits.purs b/test/Test/Data/String/NonEmpty/CodeUnits.purs index 9a33b0c..e810dd9 100644 --- a/test/Test/Data/String/NonEmpty/CodeUnits.purs +++ b/test/Test/Data/String/NonEmpty/CodeUnits.purs @@ -170,11 +170,11 @@ testNonEmptyStringCodeUnits = do log "takeWhile" assertEqual - { actual: NESCU.takeWhile (\c -> true) (nes (Proxy :: Proxy "abc")) + { actual: NESCU.takeWhile (\_ -> true) (nes (Proxy :: Proxy "abc")) , expected: Just (nes (Proxy :: Proxy "abc")) } assertEqual - { actual: NESCU.takeWhile (\c -> false) (nes (Proxy :: Proxy "abc")) + { actual: NESCU.takeWhile (\_ -> false) (nes (Proxy :: Proxy "abc")) , expected: Nothing } assertEqual @@ -192,11 +192,11 @@ testNonEmptyStringCodeUnits = do log "dropWhile" assertEqual - { actual: NESCU.dropWhile (\c -> true) (nes (Proxy :: Proxy "abc")) + { actual: NESCU.dropWhile (\_ -> true) (nes (Proxy :: Proxy "abc")) , expected: Nothing } assertEqual - { actual: NESCU.dropWhile (\c -> false) (nes (Proxy :: Proxy "abc")) + { actual: NESCU.dropWhile (\_ -> false) (nes (Proxy :: Proxy "abc")) , expected: Just (nes (Proxy :: Proxy "abc")) } assertEqual From d9ba5d0590de133d290f3a8ee12296d7bdea635b Mon Sep 17 00:00:00 2001 From: maynard Date: Fri, 25 Mar 2022 09:33:01 -0500 Subject: [PATCH 03/14] Relax Data.String.CodeUnits.slice bounds checking and drop Maybe in return type (#145) * For Data.String.CodeUnits.slice: remove bounds checking and drop `Maybe` in return type * Add changelog entry Co-authored-by: JordanMartinez --- CHANGELOG.md | 1 + src/Data/String/CodeUnits.js | 2 +- src/Data/String/CodeUnits.purs | 27 +++++++-------------------- test/Test/Data/String/CodeUnits.purs | 24 ++++++++++++++---------- 4 files changed, 23 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d63cbd2..02cb63e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Notable changes to this project are documented in this file. The format is based Breaking changes: - Migrate FFI to ES modules (#158 by @kl0tl and @JordanMartinez) - Replaced polymorphic proxies with monomorphic `Proxy` (#158 by @JordanMartinez) +- In `slice`, drop bounds checking and `Maybe` return type (#145 by Quelklef) New features: diff --git a/src/Data/String/CodeUnits.js b/src/Data/String/CodeUnits.js index 47d61f9..2608384 100644 --- a/src/Data/String/CodeUnits.js +++ b/src/Data/String/CodeUnits.js @@ -101,7 +101,7 @@ export const drop = function (n) { }; }; -export const _slice = function (b) { +export const slice = function (b) { return function (e) { return function (s) { return s.slice(b,e); diff --git a/src/Data/String/CodeUnits.purs b/src/Data/String/CodeUnits.purs index fbc1803..5fed21f 100644 --- a/src/Data/String/CodeUnits.purs +++ b/src/Data/String/CodeUnits.purs @@ -298,30 +298,17 @@ dropWhile p s = drop (countPrefix p s) s -- | Returns the substring at indices `[begin, end)`. -- | If either index is negative, it is normalised to `length s - index`, --- | where `s` is the input string. `Nothing` is returned if either +-- | where `s` is the input string. `""` is returned if either -- | index is out of bounds or if `begin > end` after normalisation. -- | -- | ```purescript --- | slice 0 0 "purescript" == Just "" --- | slice 0 1 "purescript" == Just "p" --- | slice 3 6 "purescript" == Just "esc" --- | slice (-4) (-1) "purescript" == Just "rip" --- | slice (-4) 3 "purescript" == Nothing +-- | slice 0 0 "purescript" == "" +-- | slice 0 1 "purescript" == "p" +-- | slice 3 6 "purescript" == "esc" +-- | slice (-4) (-1) "purescript" == "rip" +-- | slice (-4) 3 "purescript" == "" -- | ``` -slice :: Int -> Int -> String -> Maybe String -slice b e s = if b' < 0 || b' >= l || - e' < 0 || e' > l || - b' > e' - then Nothing - else Just (_slice b e s) - where - l = length s - norm x | x < 0 = l + x - | otherwise = x - b' = norm b - e' = norm e - -foreign import _slice :: Int -> Int -> String -> String +foreign import slice :: Int -> Int -> String -> String -- | Splits a string into two substrings, where `before` contains the -- | characters up to (but not including) the given index, and `after` contains diff --git a/test/Test/Data/String/CodeUnits.purs b/test/Test/Data/String/CodeUnits.purs index 9cf010b..ddd512b 100644 --- a/test/Test/Data/String/CodeUnits.purs +++ b/test/Test/Data/String/CodeUnits.purs @@ -472,41 +472,45 @@ testStringCodeUnits = do log "slice" assertEqual { actual: SCU.slice 0 0 "purescript" - , expected: Just "" + , expected: "" } assertEqual { actual: SCU.slice 0 1 "purescript" - , expected: Just "p" + , expected: "p" } assertEqual { actual: SCU.slice 3 6 "purescript" - , expected: Just "esc" + , expected: "esc" } assertEqual { actual: SCU.slice 3 10 "purescript" - , expected: Just "escript" + , expected: "escript" + } + assertEqual + { actual: SCU.slice 10 10 "purescript" + , expected: "" } assertEqual { actual: SCU.slice (-4) (-1) "purescript" - , expected: Just "rip" + , expected: "rip" } assertEqual { actual: SCU.slice (-4) 3 "purescript" - , expected: Nothing -- b' > e' + , expected: "" } assertEqual { actual: SCU.slice 1000 3 "purescript" - , expected: Nothing -- b' > e' (subsumes b > l) + , expected: "" } assertEqual { actual: SCU.slice 2 (-15) "purescript" - , expected: Nothing -- e' < 0 + , expected: "" } assertEqual { actual: SCU.slice (-15) 9 "purescript" - , expected: Nothing -- b' < 0 + , expected: "purescrip" } assertEqual { actual: SCU.slice 3 1000 "purescript" - , expected: Nothing -- e > l + , expected: "escript" } From bd172f8bf87d31315a9b4462b0522db2144414c9 Mon Sep 17 00:00:00 2001 From: Mohammed Anas <6daf084a-8eaf-40fb-86c7-8500077c3b69@anonaddy.me> Date: Sun, 17 Apr 2022 13:25:57 +0000 Subject: [PATCH 04/14] Fix formatting (#160) --- src/Data/String/Regex/Flags.purs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Data/String/Regex/Flags.purs b/src/Data/String/Regex/Flags.purs index dc7a0c7..822f8d1 100644 --- a/src/Data/String/Regex/Flags.purs +++ b/src/Data/String/Regex/Flags.purs @@ -23,7 +23,7 @@ noFlags = RegexFlags { global: false , ignoreCase: false , multiline: false - , dotAll : false + , dotAll: false , sticky: false , unicode: false } @@ -34,7 +34,7 @@ global = RegexFlags { global: true , ignoreCase: false , multiline: false - , dotAll : false + , dotAll: false , sticky: false , unicode: false } @@ -45,7 +45,7 @@ ignoreCase = RegexFlags { global: false , ignoreCase: true , multiline: false - , dotAll : false + , dotAll: false , sticky: false , unicode: false } @@ -56,7 +56,7 @@ multiline = RegexFlags { global: false , ignoreCase: false , multiline: true - , dotAll : false + , dotAll: false , sticky: false , unicode: false } @@ -67,7 +67,7 @@ sticky = RegexFlags { global: false , ignoreCase: false , multiline: false - , dotAll : false + , dotAll: false , sticky: true , unicode: false } @@ -78,7 +78,7 @@ unicode = RegexFlags { global: false , ignoreCase: false , multiline: false - , dotAll : false + , dotAll: false , sticky: false , unicode: true } @@ -89,7 +89,7 @@ dotAll = RegexFlags { global: false , ignoreCase: false , multiline: false - , dotAll : true + , dotAll: true , sticky: false , unicode: false } From b2565978793ecd5ad6a460009ae8d5ea5c3b9c20 Mon Sep 17 00:00:00 2001 From: Mohammed Anas <6daf084a-8eaf-40fb-86c7-8500077c3b69@anonaddy.me> Date: Sun, 17 Apr 2022 13:26:44 +0000 Subject: [PATCH 05/14] Make `RegexFlags` a `newtype` (#159) --- CHANGELOG.md | 1 + src/Data/String/Regex/Flags.purs | 14 +++++--------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02cb63e..28863e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Bugfixes: Other improvements: - Surround code with backticks in documentation (#148) +- Make `RegexFlags` a `newtype` and a `Newtype` instance for it(#159 by @mhmdanas) ## [v5.0.0](https://github.com/purescript/purescript-strings/releases/tag/v5.0.0) - 2021-02-26 diff --git a/src/Data/String/Regex/Flags.purs b/src/Data/String/Regex/Flags.purs index 822f8d1..6d7dd71 100644 --- a/src/Data/String/Regex/Flags.purs +++ b/src/Data/String/Regex/Flags.purs @@ -3,6 +3,7 @@ module Data.String.Regex.Flags where import Prelude import Control.MonadPlus (guard) +import Data.Newtype (class Newtype) import Data.String (joinWith) type RegexFlagsRec = @@ -15,7 +16,9 @@ type RegexFlagsRec = } -- | Flags that control matching. -data RegexFlags = RegexFlags RegexFlagsRec +newtype RegexFlags = RegexFlags RegexFlagsRec + +derive instance newtypeRegexFlags :: Newtype RegexFlags _ -- | All flags set to false. noFlags :: RegexFlags @@ -107,14 +110,7 @@ instance semigroupRegexFlags :: Semigroup RegexFlags where instance monoidRegexFlags :: Monoid RegexFlags where mempty = noFlags -instance eqRegexFlags :: Eq RegexFlags where - eq (RegexFlags x) (RegexFlags y) - = x.global == y.global - && x.ignoreCase == y.ignoreCase - && x.multiline == y.multiline - && x.dotAll == y.dotAll - && x.sticky == y.sticky - && x.unicode == y.unicode +derive newtype instance eqRegexFlags :: Eq RegexFlags instance showRegexFlags :: Show RegexFlags where show (RegexFlags flags) = From 4bc6954448d056f8aa7a659695a6ad60ad4fdf19 Mon Sep 17 00:00:00 2001 From: JordanMartinez Date: Wed, 27 Apr 2022 16:24:51 -0500 Subject: [PATCH 06/14] Prepare v6.0.0 release (1st PS 0.15.0-compatible release) (#161) * Update the bower dependencies * Update Node to 14 in CI * Update the changelog --- .github/workflows/ci.yml | 4 ++-- CHANGELOG.md | 10 ++++++++++ bower.json | 38 +++++++++++++++++++------------------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6ebf3a..c69237a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,9 +16,9 @@ jobs: with: purescript: "unstable" - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v2 with: - node-version: "12" + node-version: "14.x" - name: Install dependencies run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 28863e1..52a8669 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ Notable changes to this project are documented in this file. The format is based ## [Unreleased] +Breaking changes: + +New features: + +Bugfixes: + +Other improvements: + +## [v6.0.0](https://github.com/purescript/purescript-strings/releases/tag/v6.0.0) - 2022-04-27 + Breaking changes: - Migrate FFI to ES modules (#158 by @kl0tl and @JordanMartinez) - Replaced polymorphic proxies with monomorphic `Proxy` (#158 by @JordanMartinez) diff --git a/bower.json b/bower.json index 2b8dd58..cceeac4 100644 --- a/bower.json +++ b/bower.json @@ -16,26 +16,26 @@ "package.json" ], "dependencies": { - "purescript-arrays": "master", - "purescript-control": "master", - "purescript-either": "master", - "purescript-enums": "master", - "purescript-foldable-traversable": "master", - "purescript-gen": "master", - "purescript-integers": "master", - "purescript-maybe": "master", - "purescript-newtype": "master", - "purescript-nonempty": "master", - "purescript-partial": "master", - "purescript-prelude": "master", - "purescript-tailrec": "master", - "purescript-tuples": "master", - "purescript-unfoldable": "master", - "purescript-unsafe-coerce": "master" + "purescript-arrays": "^7.0.0", + "purescript-control": "^6.0.0", + "purescript-either": "^6.0.0", + "purescript-enums": "^6.0.0", + "purescript-foldable-traversable": "^6.0.0", + "purescript-gen": "^4.0.0", + "purescript-integers": "^6.0.0", + "purescript-maybe": "^6.0.0", + "purescript-newtype": "^5.0.0", + "purescript-nonempty": "^7.0.0", + "purescript-partial": "^4.0.0", + "purescript-prelude": "^6.0.0", + "purescript-tailrec": "^6.0.0", + "purescript-tuples": "^7.0.0", + "purescript-unfoldable": "^6.0.0", + "purescript-unsafe-coerce": "^6.0.0" }, "devDependencies": { - "purescript-assert": "master", - "purescript-console": "master", - "purescript-minibench": "master" + "purescript-assert": "^6.0.0", + "purescript-console": "^6.0.0", + "purescript-minibench": "^4.0.0" } } From abded947c3270cc102172b6e0302bc8f4ad86f22 Mon Sep 17 00:00:00 2001 From: JordanMartinez Date: Tue, 16 Aug 2022 17:27:30 -0500 Subject: [PATCH 07/14] Use fixed Char enums version (#163) * Use fixed Char enums version * Add changelog entry --- CHANGELOG.md | 1 + bower.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52a8669..1fdc6e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Breaking changes: New features: Bugfixes: +- Fix `Char`'s `toEnum` implementation (#163 by @JordanMartinez) Other improvements: diff --git a/bower.json b/bower.json index cceeac4..85a17c5 100644 --- a/bower.json +++ b/bower.json @@ -19,7 +19,7 @@ "purescript-arrays": "^7.0.0", "purescript-control": "^6.0.0", "purescript-either": "^6.0.0", - "purescript-enums": "^6.0.0", + "purescript-enums": "^6.0.1", "purescript-foldable-traversable": "^6.0.0", "purescript-gen": "^4.0.0", "purescript-integers": "^6.0.0", From 82c2c9a6e3bb189902357faa9396f52a5f79fa36 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 16 Aug 2022 17:30:01 -0500 Subject: [PATCH 08/14] Prep changelog for v6.0.1 --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fdc6e7..f36a713 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,14 @@ Breaking changes: New features: Bugfixes: -- Fix `Char`'s `toEnum` implementation (#163 by @JordanMartinez) Other improvements: +## [v6.0.1](https://github.com/purescript/purescript-strings/releases/tag/v6.0.1) - 2022-08-16 + +Bugfixes: +- Fix `Char`'s `toEnum` implementation (#163 by @JordanMartinez) + ## [v6.0.0](https://github.com/purescript/purescript-strings/releases/tag/v6.0.0) - 2022-04-27 Breaking changes: From 3d3e2f7197d4f7aacb15e854ee9a645489555fff Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Tue, 16 Aug 2022 17:31:08 -0500 Subject: [PATCH 09/14] v6.0.1 From 373c44a8f0ac776be836cc2d0f3b6a70a5525b07 Mon Sep 17 00:00:00 2001 From: postsolar <120750161+postsolar@users.noreply.github.com> Date: Mon, 30 Oct 2023 18:50:37 +0200 Subject: [PATCH 10/14] Better definition for `Data.String.NonEmpty.CodeUnits.fromFoldable1` (#168) --- CHANGELOG.md | 5 +++++ src/Data/String/NonEmpty/CodeUnits.purs | 6 +----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f36a713..c0def5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ Bugfixes: Other improvements: +## [v6.0.2] + +Other improvements: +- Redefine `Data.String.NonEmpty.CodeUnits.fromFoldable1` in terms of `singleton` (#168 by @postsolar) + ## [v6.0.1](https://github.com/purescript/purescript-strings/releases/tag/v6.0.1) - 2022-08-16 Bugfixes: diff --git a/src/Data/String/NonEmpty/CodeUnits.purs b/src/Data/String/NonEmpty/CodeUnits.purs index af3de43..4e97244 100644 --- a/src/Data/String/NonEmpty/CodeUnits.purs +++ b/src/Data/String/NonEmpty/CodeUnits.purs @@ -37,7 +37,6 @@ import Data.String.NonEmpty.Internal (NonEmptyString(..), fromString) import Data.String.Pattern (Pattern) import Data.String.Unsafe as U import Partial.Unsafe (unsafePartial) -import Unsafe.Coerce (unsafeCoerce) -- For internal use only. Do not export. toNonEmptyString :: String -> NonEmptyString @@ -91,10 +90,7 @@ snoc c s = toNonEmptyString (s <> CU.singleton c) -- | Creates a `NonEmptyString` from a `Foldable1` container carrying -- | characters. fromFoldable1 :: forall f. Foldable1 f => f Char -> NonEmptyString -fromFoldable1 = F1.fold1 <<< coe - where - coe ∷ f Char -> f NonEmptyString - coe = unsafeCoerce +fromFoldable1 = F1.foldMap1 singleton -- | Converts the `NonEmptyString` into an array of characters. -- | From 72bb066aaf9f6f8ab049300bdd0ff8e90e21711d Mon Sep 17 00:00:00 2001 From: Nathan Faubion Date: Mon, 30 Oct 2023 09:52:04 -0700 Subject: [PATCH 11/14] Update CHANGELOG.md Fixup bad changelog entry. --- CHANGELOG.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0def5e..878d55d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,10 +10,6 @@ New features: Bugfixes: -Other improvements: - -## [v6.0.2] - Other improvements: - Redefine `Data.String.NonEmpty.CodeUnits.fromFoldable1` in terms of `singleton` (#168 by @postsolar) From b6654d49e2300416b25c05a00a0e6065c29fcf07 Mon Sep 17 00:00:00 2001 From: Nicholas Wolverson Date: Thu, 26 Dec 2024 12:18:56 +0000 Subject: [PATCH 12/14] Update take docstring to match the behaviour (#172) --- src/Data/String/CodePoints.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/String/CodePoints.purs b/src/Data/String/CodePoints.purs index 65e0b55..610e497 100644 --- a/src/Data/String/CodePoints.purs +++ b/src/Data/String/CodePoints.purs @@ -314,7 +314,7 @@ lastIndexOf' p i s = -- | Returns a string containing the given number of code points from the -- | beginning of the given string. If the string does not have that many code --- | points, returns the empty string. Operates in constant space and in time +-- | points, returns the entire string. Operates in constant space and in time -- | linear to the given number. -- | -- | ```purescript From 03b03a7b5df720a97f9024ae612eb94bd4155399 Mon Sep 17 00:00:00 2001 From: Eryk Ciepiela Date: Fri, 5 Sep 2025 15:21:12 +0200 Subject: [PATCH 13/14] CodeUnits length function doc references itself and is wrong (#177) * CodeUnits length function doc references itself and is wrong * reference do Data.String.CodeUnits.length * referencing Data.String.CodePoints.kength from Data.String.CodeUnits.length --- src/Data/String/CodePoints.purs | 2 +- src/Data/String/CodeUnits.purs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Data/String/CodePoints.purs b/src/Data/String/CodePoints.purs index 610e497..b695364 100644 --- a/src/Data/String/CodePoints.purs +++ b/src/Data/String/CodePoints.purs @@ -207,7 +207,7 @@ uncons s = case CU.length s of -- | ```purescript -- | >>> length "b 𝐀𝐀 c 𝐀" -- | 8 --- | -- compare to Data.String: +-- | -- compare to Data.String.CodeUnits: -- | >>> length "b 𝐀𝐀 c 𝐀" -- | 11 -- | ``` diff --git a/src/Data/String/CodeUnits.purs b/src/Data/String/CodeUnits.purs index 5fed21f..ac78266 100644 --- a/src/Data/String/CodeUnits.purs +++ b/src/Data/String/CodeUnits.purs @@ -145,6 +145,10 @@ uncons s = Just { head: U.charAt zero s, tail: drop one s } -- | -- | ```purescript -- | length "Hello World" == 11 +-- | +-- | length "𝐀A" == 3 +-- | -- compare to Data.String.CodePoints: +-- | length "𝐀A" == 2 -- | ``` -- | foreign import length :: String -> Int From 1c9cde35c87d9b1626cf6d4b3c38c548fa45e91d Mon Sep 17 00:00:00 2001 From: triallax <6daf084a-8eaf-40fb-86c7-8500077c3b69@anonaddy.me> Date: Fri, 10 Apr 2026 22:16:25 +0000 Subject: [PATCH 14/14] Add startsWith and endsWith (#147) --- CHANGELOG.md | 1 + src/Data/String/CodePoints.purs | 2 +- src/Data/String/CodeUnits.purs | 33 +++++++++++++++++++++++--- src/Data/String/NonEmpty.purs | 2 +- src/Data/String/NonEmpty/Internal.purs | 25 +++++++++++++++++++ test/Test/Data/String/CodeUnits.purs | 14 +++++++++++ test/Test/Data/String/NonEmpty.purs | 13 ++++++++++ 7 files changed, 85 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 878d55d..f0f30c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Notable changes to this project are documented in this file. The format is based Breaking changes: New features: +- Added `startsWith` and `endsWith` (#147) Bugfixes: diff --git a/src/Data/String/CodePoints.purs b/src/Data/String/CodePoints.purs index b695364..f5b5fd2 100644 --- a/src/Data/String/CodePoints.purs +++ b/src/Data/String/CodePoints.purs @@ -34,7 +34,7 @@ import Data.Array as Array import Data.Enum (class BoundedEnum, class Enum, Cardinality(..), defaultPred, defaultSucc, fromEnum, toEnum, toEnumWithDefaults) import Data.Int (hexadecimal, toStringAs) import Data.Maybe (Maybe(..)) -import Data.String.CodeUnits (contains, stripPrefix, stripSuffix) as Exports +import Data.String.CodeUnits (contains, stripPrefix, stripSuffix, startsWith, endsWith) as Exports import Data.String.CodeUnits as CU import Data.String.Common (toUpper) import Data.String.Pattern (Pattern) diff --git a/src/Data/String/CodeUnits.purs b/src/Data/String/CodeUnits.purs index ac78266..ec4d4cd 100644 --- a/src/Data/String/CodeUnits.purs +++ b/src/Data/String/CodeUnits.purs @@ -22,6 +22,8 @@ module Data.String.CodeUnits , dropWhile , slice , splitAt + , startsWith + , endsWith ) where import Prelude @@ -31,9 +33,10 @@ import Data.String.Pattern (Pattern(..)) import Data.String.Unsafe as U ------------------------------------------------------------------------------- --- `stripPrefix`, `stripSuffix`, and `contains` are CodeUnit/CodePoint agnostic --- as they are based on patterns rather than lengths/indices, but they need to --- be defined in here to avoid a circular module dependency +-- `stripPrefix`, `stripSuffix`, `startsWith`, `endsWith`, and `contains` are +-- CodeUnit/CodePoint agnostic as they are based on patterns rather than +-- lengths/indices, but they need to be defined in here to avoid a circular +-- module dependency ------------------------------------------------------------------------------- -- | If the string starts with the given prefix, return the portion of the @@ -61,6 +64,30 @@ stripSuffix (Pattern suffix) str = let { before, after } = splitAt (length str - length suffix) str in if after == suffix then Just before else Nothing +-- | Checks whether the given string starts with the pattern. +-- | +-- | **NOTE**: if you also want to get the string stripped of the pattern, see +-- | `stripPrefix`. +-- | +-- | ```purescript +-- | startsWith (Pattern "foo") "foobar" == true +-- | startsWith (Pattern "bar") "foobar" == false +-- | ``` +startsWith :: Pattern -> String -> Boolean +startsWith pat = isJust <<< stripPrefix pat + +-- | Checks whether the given string ends with the pattern. +-- | +-- | **NOTE**: if you also want to get the string stripped of the pattern, see +-- | `stripSuffix`. +-- | +-- | ```purescript +-- | endsWith (Pattern "bar") "foobar" == true +-- | endsWith (Pattern "foo") "foobar" == false +-- | ``` +endsWith :: Pattern -> String -> Boolean +endsWith pat = isJust <<< stripSuffix pat + -- | Checks whether the pattern appears in the given string. -- | -- | ```purescript diff --git a/src/Data/String/NonEmpty.purs b/src/Data/String/NonEmpty.purs index 6b6210c..72e10b3 100644 --- a/src/Data/String/NonEmpty.purs +++ b/src/Data/String/NonEmpty.purs @@ -4,6 +4,6 @@ module Data.String.NonEmpty , module Data.String.NonEmpty.CodePoints ) where -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) +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) import Data.String.Pattern (Pattern(..)) import Data.String.NonEmpty.CodePoints diff --git a/src/Data/String/NonEmpty/Internal.purs b/src/Data/String/NonEmpty/Internal.purs index 8722654..0b12623 100644 --- a/src/Data/String/NonEmpty/Internal.purs +++ b/src/Data/String/NonEmpty/Internal.purs @@ -124,6 +124,31 @@ stripPrefix pat = fromString <=< liftS (String.stripPrefix pat) stripSuffix :: Pattern -> NonEmptyString -> Maybe NonEmptyString stripSuffix pat = fromString <=< liftS (String.stripSuffix pat) + +-- | Checks whether the given string starts with the pattern. +-- | +-- | **NOTE**: if you also want to get the string stripped of the pattern, see +-- | `stripPrefix`. +-- | +-- | ```purescript +-- | startsWith (Pattern "foo") (NonEmptyString "foobar") == true +-- | startsWith (Pattern "bar") (NonEmptyString "foobar") == false +-- | ``` +startsWith :: Pattern -> NonEmptyString -> Boolean +startsWith = liftS <<< String.startsWith + +-- | Checks whether the given string ends with the pattern. +-- | +-- | **NOTE**: if you also want to get the string stripped of the pattern, see +-- | `stripSuffix`. +-- | +-- | ```purescript +-- | endsWith (Pattern "bar") (NonEmptyString "foobar") == true +-- | endsWith (Pattern "foo") (NonEmptyString "foobar") == false +-- | ``` +endsWith :: Pattern -> NonEmptyString -> Boolean +endsWith = liftS <<< String.endsWith + -- | Checks whether the pattern appears in the given string. -- | -- | ```purescript diff --git a/test/Test/Data/String/CodeUnits.purs b/test/Test/Data/String/CodeUnits.purs index ddd512b..30bf100 100644 --- a/test/Test/Data/String/CodeUnits.purs +++ b/test/Test/Data/String/CodeUnits.purs @@ -64,6 +64,20 @@ testStringCodeUnits = do , expected: Just "" } + log "startsWith" + assert $ SCU.startsWith (Pattern "foo") "foobar" + assert $ SCU.startsWith (Pattern "foo") "foo" + assert $ SCU.startsWith (Pattern "") "" + assert $ SCU.startsWith (Pattern "") "foo" + assert $ not $ SCU.startsWith (Pattern "foo") "" + + log "endsWith" + assert $ SCU.endsWith (Pattern "bar") "foobar" + assert $ SCU.endsWith (Pattern "bar") "bar" + assert $ SCU.endsWith (Pattern "") "" + assert $ SCU.endsWith (Pattern "") "bar" + assert $ not $ SCU.endsWith (Pattern "bar") "" + log "charAt" assertEqual { actual: SCU.charAt 0 "" diff --git a/test/Test/Data/String/NonEmpty.purs b/test/Test/Data/String/NonEmpty.purs index a4103ec..46f2cd0 100644 --- a/test/Test/Data/String/NonEmpty.purs +++ b/test/Test/Data/String/NonEmpty.purs @@ -144,6 +144,19 @@ testNonEmptyString = do , expected: Nothing } + log "startsWith" + assert $ NES.startsWith (Pattern "foo") (nes (Proxy :: Proxy "foobar")) + assert $ NES.startsWith (Pattern "foo") (nes (Proxy :: Proxy "foo")) + assert $ NES.startsWith (Pattern "") (nes (Proxy :: Proxy "foo")) + assert $ not $ NES.startsWith (Pattern "foo") (nes (Proxy :: Proxy "f")) + + log "endsWith" + assert $ NES.endsWith (Pattern "bar") (nes (Proxy :: Proxy "foobar")) + assert $ NES.endsWith (Pattern "bar") (nes (Proxy :: Proxy "bar")) + assert $ NES.endsWith (Pattern "") (nes (Proxy :: Proxy "f")) + assert $ NES.endsWith (Pattern "") (nes (Proxy :: Proxy "bar")) + assert $ not $ NES.endsWith (Pattern "bar") (nes (Proxy :: Proxy "b")) + log "toLower" assertEqual { actual: NES.toLower (nes (Proxy :: Proxy "bAtMaN"))