312 |
312 |
313 class (IsString a, Monoid a, Eq a, Ord a) => StringLike a where |
313 class (IsString a, Monoid a, Eq a, Ord a) => StringLike a where |
314 space_explode :: Char -> a -> [a] |
314 space_explode :: Char -> a -> [a] |
315 trim_line :: a -> a |
315 trim_line :: a -> a |
316 |
316 |
|
317 gen_trim_line :: Int -> (Int -> Char) -> (Int -> a -> a) -> a -> a |
|
318 gen_trim_line n at trim s = |
|
319 if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then trim (n - 2) s |
|
320 else if n >= 1 && Symbol.is_ascii_line_terminator (at (n - 1)) then trim (n - 1) s |
|
321 else s |
|
322 |
317 instance StringLike String where |
323 instance StringLike String where |
318 space_explode :: Char -> String -> [String] |
324 space_explode :: Char -> String -> [String] |
319 space_explode c = Split.split (Split.dropDelims (Split.whenElt (== c))) |
325 space_explode c = Split.split (Split.dropDelims (Split.whenElt (== c))) |
320 trim_line :: String -> String |
326 trim_line :: String -> String |
321 trim_line s = |
327 trim_line s = gen_trim_line (length s) ((!!) s) take s |
322 if not (null s) && Symbol.is_ascii_line_terminator (last s) then |
|
323 case reverse s of |
|
324 '\n' : '\r' : rest -> reverse rest |
|
325 '\r' : rest -> reverse rest |
|
326 '\n' : rest -> reverse rest |
|
327 _ -> s |
|
328 else s |
|
329 |
328 |
330 instance StringLike Text where |
329 instance StringLike Text where |
331 space_explode :: Char -> Text -> [Text] |
330 space_explode :: Char -> Text -> [Text] |
332 space_explode c str = |
331 space_explode c str = |
333 if Text.null str then [] |
332 if Text.null str then [] |
334 else if Text.all (/= c) str then [str] |
333 else if Text.all (/= c) str then [str] |
335 else map Text.pack $ space_explode c $ Text.unpack str |
334 else map Text.pack $ space_explode c $ Text.unpack str |
336 trim_line :: Text -> Text |
335 trim_line :: Text -> Text |
337 trim_line s = |
336 trim_line s = gen_trim_line (Text.length s) (Text.index s) Text.take s |
338 if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then Text.take (n - 2) s |
|
339 else if n >= 1 && Symbol.is_ascii_line_terminator (at (n - 1)) then Text.take (n - 1) s |
|
340 else s |
|
341 where |
|
342 n = Text.length s |
|
343 at = Text.index s |
|
344 |
337 |
345 instance StringLike Lazy.Text where |
338 instance StringLike Lazy.Text where |
346 space_explode :: Char -> Lazy.Text -> [Lazy.Text] |
339 space_explode :: Char -> Lazy.Text -> [Lazy.Text] |
347 space_explode c str = |
340 space_explode c str = |
348 if Lazy.null str then [] |
341 if Lazy.null str then [] |
362 explode rest = |
355 explode rest = |
363 case span (/= (Bytes.byte c)) rest of |
356 case span (/= (Bytes.byte c)) rest of |
364 (_, []) -> [Bytes.pack rest] |
357 (_, []) -> [Bytes.pack rest] |
365 (prfx, _ : rest') -> Bytes.pack prfx : explode rest' |
358 (prfx, _ : rest') -> Bytes.pack prfx : explode rest' |
366 trim_line :: Bytes -> Bytes |
359 trim_line :: Bytes -> Bytes |
367 trim_line s = |
360 trim_line s = gen_trim_line (Bytes.length s) (Bytes.char . Bytes.index s) Bytes.take s |
368 if n >= 2 && at (n - 2) == '\r' && at (n - 1) == '\n' then Bytes.take (n - 2) s |
|
369 else if n >= 1 && Symbol.is_ascii_line_terminator (at (n - 1)) then Bytes.take (n - 1) s |
|
370 else s |
|
371 where |
|
372 n = Bytes.length s |
|
373 at = Bytes.char . Bytes.index s |
|
374 |
361 |
375 class StringLike a => STRING a where make_string :: a -> String |
362 class StringLike a => STRING a where make_string :: a -> String |
376 instance STRING String where make_string = id |
363 instance STRING String where make_string = id |
377 instance STRING Text where make_string = Text.unpack |
364 instance STRING Text where make_string = Text.unpack |
378 instance STRING Lazy.Text where make_string = Lazy.unpack |
365 instance STRING Lazy.Text where make_string = Lazy.unpack |