|
1 | 1 | module Data.String.NonEmpty
|
2 |
| - ( NonEmptyString |
3 |
| - , class MakeNonEmpty, nes |
4 |
| - , NonEmptyReplacement(..) |
5 |
| - , fromString |
6 |
| - , unsafeFromString |
7 |
| - , toString |
8 |
| - , appendString |
9 |
| - , prependString |
10 |
| - , contains |
11 |
| - , localeCompare |
12 |
| - , replace |
13 |
| - , replaceAll |
14 |
| - , stripPrefix |
15 |
| - , stripSuffix |
16 |
| - , toLower |
17 |
| - , toUpper |
18 |
| - , trim |
19 |
| - , joinWith |
20 |
| - , join1With |
21 |
| - , joinWith1 |
22 |
| - , module Data.String.Pattern |
| 2 | + ( module Data.String.Pattern |
| 3 | + , module Data.String.NonEmpty.Internal |
| 4 | + , module Data.String.NonEmpty.CodePoints |
23 | 5 | ) where
|
24 | 6 |
|
25 |
| -import Prelude |
26 |
| - |
27 |
| -import Data.Foldable (class Foldable) |
28 |
| -import Data.Foldable as F |
29 |
| -import Data.Maybe (Maybe(..), fromJust) |
30 |
| -import Data.Semigroup.Foldable (class Foldable1) |
31 |
| -import Data.String as String |
| 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) |
32 | 8 | import Data.String.Pattern (Pattern(..))
|
33 |
| -import Data.Symbol (class IsSymbol, SProxy, reflectSymbol) |
34 |
| -import Prim.TypeError as TE |
35 |
| -import Unsafe.Coerce (unsafeCoerce) |
36 |
| - |
37 |
| --- | A string that is known not to be empty. |
38 |
| -newtype NonEmptyString = NonEmptyString String |
39 |
| - |
40 |
| -derive newtype instance eqNonEmptyString ∷ Eq NonEmptyString |
41 |
| -derive newtype instance ordNonEmptyString ∷ Ord NonEmptyString |
42 |
| -derive newtype instance semigroupNonEmptyString ∷ Semigroup NonEmptyString |
43 |
| - |
44 |
| -instance showNonEmptyString :: Show NonEmptyString where |
45 |
| - show (NonEmptyString s) = "(NonEmptyString.unsafeFromString " <> show s <> ")" |
46 |
| - |
47 |
| --- | A helper class for defining non-empty string values at compile time. |
48 |
| --- | |
49 |
| --- | ``` purescript |
50 |
| --- | something :: NonEmptyString |
51 |
| --- | something = nes (SProxy :: SProxy "something") |
52 |
| --- | ``` |
53 |
| -class MakeNonEmpty (s :: Symbol) where |
54 |
| - nes :: SProxy s -> NonEmptyString |
55 |
| - |
56 |
| -instance makeNonEmptyBad :: TE.Fail (TE.Text "Cannot create an NonEmptyString from an empty Symbol") => MakeNonEmpty "" where |
57 |
| - nes _ = NonEmptyString "" |
58 |
| - |
59 |
| -else instance nonEmptyNonEmpty :: IsSymbol s => MakeNonEmpty s where |
60 |
| - nes p = NonEmptyString (reflectSymbol p) |
61 |
| - |
62 |
| --- | A newtype used in cases to specify a non-empty replacement for a pattern. |
63 |
| -newtype NonEmptyReplacement = NonEmptyReplacement NonEmptyString |
64 |
| - |
65 |
| -derive newtype instance eqNonEmptyReplacement :: Eq NonEmptyReplacement |
66 |
| -derive newtype instance ordNonEmptyReplacement :: Ord NonEmptyReplacement |
67 |
| -derive newtype instance semigroupNonEmptyReplacement ∷ Semigroup NonEmptyReplacement |
68 |
| - |
69 |
| -instance showNonEmptyReplacement :: Show NonEmptyReplacement where |
70 |
| - show (NonEmptyReplacement s) = "(NonEmptyReplacement " <> show s <> ")" |
71 |
| - |
72 |
| --- | Creates a `NonEmptyString` from a `String`, returning `Nothing` if the |
73 |
| --- | input is empty. |
74 |
| --- | |
75 |
| --- | ```purescript |
76 |
| --- | fromString "" = Nothing |
77 |
| --- | fromString "hello" = Just (NES.unsafeFromString "hello") |
78 |
| --- | ``` |
79 |
| -fromString :: String -> Maybe NonEmptyString |
80 |
| -fromString = case _ of |
81 |
| - "" -> Nothing |
82 |
| - s -> Just (NonEmptyString s) |
83 |
| - |
84 |
| --- | A partial version of `fromString`. |
85 |
| -unsafeFromString :: Partial => String -> NonEmptyString |
86 |
| -unsafeFromString = fromJust <<< fromString |
87 |
| - |
88 |
| --- | Converts a `NonEmptyString` back into a standard `String`. |
89 |
| -toString :: NonEmptyString -> String |
90 |
| -toString (NonEmptyString s) = s |
91 |
| - |
92 |
| --- | Appends a string to this non-empty string. Since one of the strings is |
93 |
| --- | non-empty we know the result will be too. |
94 |
| --- | |
95 |
| --- | ```purescript |
96 |
| --- | appendString (NonEmptyString "Hello") " world" == NonEmptyString "Hello world" |
97 |
| --- | appendString (NonEmptyString "Hello") "" == NonEmptyString "Hello" |
98 |
| --- | ``` |
99 |
| -appendString :: NonEmptyString -> String -> NonEmptyString |
100 |
| -appendString (NonEmptyString s1) s2 = NonEmptyString (s1 <> s2) |
101 |
| - |
102 |
| --- | Prepends a string to this non-empty string. Since one of the strings is |
103 |
| --- | non-empty we know the result will be too. |
104 |
| --- | |
105 |
| --- | ```purescript |
106 |
| --- | prependString "be" (NonEmptyString "fore") == NonEmptyString "before" |
107 |
| --- | prependString "" (NonEmptyString "fore") == NonEmptyString "fore" |
108 |
| --- | ``` |
109 |
| -prependString :: String -> NonEmptyString -> NonEmptyString |
110 |
| -prependString s1 (NonEmptyString s2) = NonEmptyString (s1 <> s2) |
111 |
| - |
112 |
| --- | If the string starts with the given prefix, return the portion of the |
113 |
| --- | string left after removing it. If the prefix does not match or there is no |
114 |
| --- | remainder, the result will be `Nothing`. |
115 |
| --- | |
116 |
| --- | ```purescript |
117 |
| --- | stripPrefix (Pattern "http:") (NonEmptyString "http://purescript.org") == Just (NonEmptyString "//purescript.org") |
118 |
| --- | stripPrefix (Pattern "http:") (NonEmptyString "https://purescript.org") == Nothing |
119 |
| --- | stripPrefix (Pattern "Hello!") (NonEmptyString "Hello!") == Nothing |
120 |
| --- | ``` |
121 |
| -stripPrefix :: Pattern -> NonEmptyString -> Maybe NonEmptyString |
122 |
| -stripPrefix pat = fromString <=< liftS (String.stripPrefix pat) |
123 |
| - |
124 |
| --- | If the string ends with the given suffix, return the portion of the |
125 |
| --- | string left after removing it. If the suffix does not match or there is no |
126 |
| --- | remainder, the result will be `Nothing`. |
127 |
| --- | |
128 |
| --- | ```purescript |
129 |
| --- | stripSuffix (Pattern ".exe") (NonEmptyString "purs.exe") == Just (NonEmptyString "purs") |
130 |
| --- | stripSuffix (Pattern ".exe") (NonEmptyString "purs") == Nothing |
131 |
| --- | stripSuffix (Pattern "Hello!") (NonEmptyString "Hello!") == Nothing |
132 |
| --- | ``` |
133 |
| -stripSuffix :: Pattern -> NonEmptyString -> Maybe NonEmptyString |
134 |
| -stripSuffix pat = fromString <=< liftS (String.stripSuffix pat) |
135 |
| - |
136 |
| --- | Checks whether the pattern appears in the given string. |
137 |
| --- | |
138 |
| --- | ```purescript |
139 |
| --- | contains (Pattern "needle") (NonEmptyString "haystack with needle") == true |
140 |
| --- | contains (Pattern "needle") (NonEmptyString "haystack") == false |
141 |
| --- | ``` |
142 |
| -contains :: Pattern -> NonEmptyString -> Boolean |
143 |
| -contains = liftS <<< String.contains |
144 |
| - |
145 |
| --- | Compare two strings in a locale-aware fashion. This is in contrast to |
146 |
| --- | the `Ord` instance on `String` which treats strings as arrays of code |
147 |
| --- | units: |
148 |
| --- | |
149 |
| --- | ```purescript |
150 |
| --- | NonEmptyString "ä" `localeCompare` NonEmptyString "b" == LT |
151 |
| --- | NonEmptyString "ä" `compare` NonEmptyString "b" == GT |
152 |
| --- | ``` |
153 |
| -localeCompare :: NonEmptyString -> NonEmptyString -> Ordering |
154 |
| -localeCompare (NonEmptyString a) (NonEmptyString b) = String.localeCompare a b |
155 |
| - |
156 |
| --- | Replaces the first occurence of the pattern with the replacement string. |
157 |
| --- | |
158 |
| --- | ```purescript |
159 |
| --- | replace (Pattern "<=") (NonEmptyReplacement "≤") (NonEmptyString "a <= b <= c") == NonEmptyString "a ≤ b <= c" |
160 |
| --- | ``` |
161 |
| -replace :: Pattern -> NonEmptyReplacement -> NonEmptyString -> NonEmptyString |
162 |
| -replace pat (NonEmptyReplacement (NonEmptyString rep)) (NonEmptyString s) = |
163 |
| - NonEmptyString (String.replace pat (String.Replacement rep) s) |
164 |
| - |
165 |
| --- | Replaces all occurences of the pattern with the replacement string. |
166 |
| --- | |
167 |
| --- | ```purescript |
168 |
| --- | replaceAll (Pattern "<=") (NonEmptyReplacement "≤") (NonEmptyString "a <= b <= c") == NonEmptyString "a ≤ b ≤ c" |
169 |
| --- | ``` |
170 |
| -replaceAll :: Pattern -> NonEmptyReplacement -> NonEmptyString -> NonEmptyString |
171 |
| -replaceAll pat (NonEmptyReplacement (NonEmptyString rep)) (NonEmptyString s) = |
172 |
| - NonEmptyString (String.replaceAll pat (String.Replacement rep) s) |
173 |
| - |
174 |
| --- | Returns the argument converted to lowercase. |
175 |
| --- | |
176 |
| --- | ```purescript |
177 |
| --- | toLower (NonEmptyString "hElLo") == NonEmptyString "hello" |
178 |
| --- | ``` |
179 |
| -toLower :: NonEmptyString -> NonEmptyString |
180 |
| -toLower (NonEmptyString s) = NonEmptyString (String.toLower s) |
181 |
| - |
182 |
| --- | Returns the argument converted to uppercase. |
183 |
| --- | |
184 |
| --- | ```purescript |
185 |
| --- | toUpper (NonEmptyString "Hello") == NonEmptyString "HELLO" |
186 |
| --- | ``` |
187 |
| -toUpper :: NonEmptyString -> NonEmptyString |
188 |
| -toUpper (NonEmptyString s) = NonEmptyString (String.toUpper s) |
189 |
| - |
190 |
| --- | Removes whitespace from the beginning and end of a string, including |
191 |
| --- | [whitespace characters](http://www.ecma-international.org/ecma-262/5.1/#sec-7.2) |
192 |
| --- | and [line terminators](http://www.ecma-international.org/ecma-262/5.1/#sec-7.3). |
193 |
| --- | If the string is entirely made up of whitespace the result will be Nothing. |
194 |
| --- | |
195 |
| --- | ```purescript |
196 |
| --- | trim (NonEmptyString " Hello \n World\n\t ") == Just (NonEmptyString "Hello \n World") |
197 |
| --- | trim (NonEmptyString " \n") == Nothing |
198 |
| --- | ``` |
199 |
| -trim :: NonEmptyString -> Maybe NonEmptyString |
200 |
| -trim (NonEmptyString s) = fromString (String.trim s) |
201 |
| - |
202 |
| --- | Joins the strings in a container together as a new string, inserting the |
203 |
| --- | first argument as separator between them. The result is not guaranteed to |
204 |
| --- | be non-empty. |
205 |
| --- | |
206 |
| --- | ```purescript |
207 |
| --- | joinWith ", " [NonEmptyString "apple", NonEmptyString "banana"] == "apple, banana" |
208 |
| --- | joinWith ", " [] == "" |
209 |
| --- | ``` |
210 |
| -joinWith :: forall f. Foldable f => String -> f NonEmptyString -> String |
211 |
| -joinWith splice = F.intercalate splice <<< coe |
212 |
| - where |
213 |
| - coe :: f NonEmptyString -> f String |
214 |
| - coe = unsafeCoerce |
215 |
| - |
216 |
| --- | Joins non-empty strings in a non-empty container together as a new |
217 |
| --- | non-empty string, inserting a possibly empty string as separator between |
218 |
| --- | them. The result is guaranteed to be non-empty. |
219 |
| --- | |
220 |
| --- | ```purescript |
221 |
| --- | -- array syntax is used for demonstration here, it would need to be a real `Foldable1` |
222 |
| --- | join1With ", " [NonEmptyString "apple", NonEmptyString "banana"] == NonEmptyString "apple, banana" |
223 |
| --- | join1With "" [NonEmptyString "apple", NonEmptyString "banana"] == NonEmptyString "applebanana" |
224 |
| --- | ``` |
225 |
| -join1With :: forall f. Foldable1 f => String -> f NonEmptyString -> NonEmptyString |
226 |
| -join1With splice = NonEmptyString <<< joinWith splice |
227 |
| - |
228 |
| --- | Joins possibly empty strings in a non-empty container together as a new |
229 |
| --- | non-empty string, inserting a non-empty string as a separator between them. |
230 |
| --- | The result is guaranteed to be non-empty. |
231 |
| --- | |
232 |
| --- | ```purescript |
233 |
| --- | -- array syntax is used for demonstration here, it would need to be a real `Foldable1` |
234 |
| --- | joinWith1 (NonEmptyString ", ") ["apple", "banana"] == NonEmptyString "apple, banana" |
235 |
| --- | joinWith1 (NonEmptyString "/") ["a", "b", "", "c", ""] == NonEmptyString "a/b//c/" |
236 |
| --- | ``` |
237 |
| -joinWith1 :: forall f. Foldable1 f => NonEmptyString -> f String -> NonEmptyString |
238 |
| -joinWith1 (NonEmptyString splice) = NonEmptyString <<< F.intercalate splice |
239 |
| - |
240 |
| -liftS :: forall r. (String -> r) -> NonEmptyString -> r |
241 |
| -liftS f (NonEmptyString s) = f s |
| 9 | +import Data.String.NonEmpty.CodePoints |
0 commit comments