module Conferer.Key.Internal where
import Data.String (IsString(..))
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Function (on)
import Data.List (stripPrefix, isPrefixOf)
import qualified Data.Char as Char
newtype Key = Key
{ Key -> [Text]
unKey :: [Text]
} deriving (Key -> Key -> Bool
(Key -> Key -> Bool) -> (Key -> Key -> Bool) -> Eq Key
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Key -> Key -> Bool
$c/= :: Key -> Key -> Bool
== :: Key -> Key -> Bool
$c== :: Key -> Key -> Bool
Eq, Eq Key
Eq Key
-> (Key -> Key -> Ordering)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Key)
-> (Key -> Key -> Key)
-> Ord Key
Key -> Key -> Bool
Key -> Key -> Ordering
Key -> Key -> Key
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Key -> Key -> Key
$cmin :: Key -> Key -> Key
max :: Key -> Key -> Key
$cmax :: Key -> Key -> Key
>= :: Key -> Key -> Bool
$c>= :: Key -> Key -> Bool
> :: Key -> Key -> Bool
$c> :: Key -> Key -> Bool
<= :: Key -> Key -> Bool
$c<= :: Key -> Key -> Bool
< :: Key -> Key -> Bool
$c< :: Key -> Key -> Bool
compare :: Key -> Key -> Ordering
$ccompare :: Key -> Key -> Ordering
$cp1Ord :: Eq Key
Ord)
instance Show Key where
show :: Key -> String
show Key
key = String
"\"" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
Text.unpack (Key -> Text
keyName Key
key) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\""
instance IsString Key where
fromString :: String -> Key
fromString = String -> Key
mkKey
mkKey :: String -> Key
mkKey :: String -> Key
mkKey String
s =
[Text] -> Key
Key ([Text] -> Key) -> (String -> [Text]) -> String -> Key
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
forall a. Monoid a => a
mempty) ([Text] -> [Text]) -> (String -> [Text]) -> String -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(Text -> Text) -> [Text] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Char -> Bool) -> Text -> Text
Text.filter Char -> Bool
isKeyCharacter (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
Text.toLower) ([Text] -> [Text]) -> (String -> [Text]) -> String -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
(Char -> Bool) -> Text -> [Text]
Text.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.') (Text -> [Text]) -> (String -> Text) -> String -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
String -> Text
forall a. IsString a => String -> a
fromString
(String -> Key) -> String -> Key
forall a b. (a -> b) -> a -> b
$ String
s
fromText :: Text -> Key
fromText :: Text -> Key
fromText = String -> Key
mkKey (String -> Key) -> (Text -> String) -> Text -> Key
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
Text.unpack
keyName :: Key -> Text
keyName :: Key -> Text
keyName = Text -> [Text] -> Text
Text.intercalate Text
"." ([Text] -> Text) -> (Key -> [Text]) -> Key -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> [Text]
unKey
isKeyPrefixOf :: Key -> Key -> Bool
isKeyPrefixOf :: Key -> Key -> Bool
isKeyPrefixOf = [Text] -> [Text] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isPrefixOf ([Text] -> [Text] -> Bool) -> (Key -> [Text]) -> Key -> Key -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Key -> [Text]
unKey
stripKeyPrefix :: Key -> Key -> Maybe Key
stripKeyPrefix :: Key -> Key -> Maybe Key
stripKeyPrefix Key
key1 Key
key2 = [Text] -> Key
Key ([Text] -> Key) -> Maybe [Text] -> Maybe Key
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([Text] -> [Text] -> Maybe [Text]
forall a. Eq a => [a] -> [a] -> Maybe [a]
stripPrefix ([Text] -> [Text] -> Maybe [Text])
-> (Key -> [Text]) -> Key -> Key -> Maybe [Text]
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Key -> [Text]
unKey) Key
key1 Key
key2
(/.) :: Key -> Key -> Key
Key
parent /. :: Key -> Key -> Key
/. Key
child = [Text] -> Key
Key (Key -> [Text]
unKey Key
parent [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ Key -> [Text]
unKey Key
child)
rawKeyComponents :: Key -> [Text]
rawKeyComponents :: Key -> [Text]
rawKeyComponents = Key -> [Text]
unKey
unconsKey :: Key -> Maybe (Text, Key)
unconsKey :: Key -> Maybe (Text, Key)
unconsKey (Key []) = Maybe (Text, Key)
forall a. Maybe a
Nothing
unconsKey (Key (Text
k:[Text]
ks)) = (Text, Key) -> Maybe (Text, Key)
forall a. a -> Maybe a
Just (Text
k, [Text] -> Key
Key [Text]
ks)
isValidKeyFragment :: Text -> Bool
isValidKeyFragment :: Text -> Bool
isValidKeyFragment Text
t =
(Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Text -> Bool
Text.null Text
t) Bool -> Bool -> Bool
&& (Char -> Bool) -> Text -> Bool
Text.all Char -> Bool
isKeyCharacter Text
t
isKeyCharacter :: Char -> Bool
isKeyCharacter :: Char -> Bool
isKeyCharacter Char
c =
Char -> Bool
Char.isAsciiLower Char
c Bool -> Bool -> Bool
|| Char -> Bool
Char.isDigit Char
c