module U.Util.Text
( stripMargin,
unsafeToInt,
)
where
import Data.Char qualified as Char
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import Data.Text qualified as Text
import Data.Text.Read qualified as Text
import GHC.Stack (HasCallStack)
import Safe.Foldable (minimumMay)
import Unison.Prelude (reportBug)
stripMargin :: Text -> Text
stripMargin :: Text -> Text
stripMargin Text
str =
let stripLen :: Int
stripLen =
Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
Data.Maybe.fromMaybe Int
0
(Maybe Int -> Int) -> ([Text] -> Maybe Int) -> [Text] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> Maybe Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> Maybe a
minimumMay
([Int] -> Maybe Int) -> ([Text] -> [Int]) -> [Text] -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Int) -> [Text] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> Int
Text.length (Text -> Int) -> (Text -> Text) -> Text -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, Text) -> Text
forall a b. (a, b) -> a
fst ((Text, Text) -> Text) -> (Text -> (Text, Text)) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> (Text, Text)
Text.span (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' '))
([Text] -> [Int]) -> ([Text] -> [Text]) -> [Text] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> Bool
Text.all (Char -> Bool
Char.isSpace))
([Text] -> Int) -> [Text] -> Int
forall a b. (a -> b) -> a -> b
$ Text -> [Text]
Text.lines Text
str
dropFirstIf :: (t -> Bool) -> [t] -> [t]
dropFirstIf t -> Bool
f = \case
t
h : [t]
t | t -> Bool
f t
h -> [t]
t
[t]
x -> [t]
x
dropLastIf :: (a -> Bool) -> [a] -> [a]
dropLastIf a -> Bool
f = [a] -> [a]
forall a. [a] -> [a]
reverse ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
dropFirstIf a -> Bool
f ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
forall a. [a] -> [a]
reverse
in [Text] -> Text
Text.unlines
([Text] -> Text) -> ([Text] -> [Text]) -> [Text] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
dropLastIf Text -> Bool
Text.null
([Text] -> [Text]) -> ([Text] -> [Text]) -> [Text] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
dropFirstIf Text -> Bool
Text.null
([Text] -> [Text]) -> ([Text] -> [Text]) -> [Text] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Text -> Text
Text.drop Int
stripLen)
([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Text -> [Text]
Text.lines Text
str
unsafeToInt :: (HasCallStack) => Text -> Int
unsafeToInt :: HasCallStack => Text -> Int
unsafeToInt Text
text =
case Reader Int
forall a. Integral a => Reader a
Text.decimal Text
text of
Right (Int
n, Text
"") -> Int
n
Either [Char] (Int, Text)
_ -> [Char] -> Int
forall a. HasCallStack => [Char] -> a
error ([Char] -> [Char] -> [Char]
reportBug [Char]
"E573530" ([Char]
"not an int: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
Text.unpack Text
text))