|
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