{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- | Abstract representation for paths into modules.
module Data.GI.CodeGen.ModulePath
  ( ModulePath(..)
  , toModulePath
  , (/.)
  , dotModulePath
  ) where

#if !MIN_VERSION_base(4,13,0)
import Data.Monoid (Monoid(..), (<>))
#endif
import Data.String (IsString(..))
import qualified Data.Text as T
import qualified Data.Semigroup as Sem
import Data.Text (Text)

import Data.GI.CodeGen.Util (ucFirst)

-- | A path to a module.
newtype ModulePath = ModulePath { ModulePath -> [Text]
modulePathToList :: [Text] }
  deriving (NonEmpty ModulePath -> ModulePath
ModulePath -> ModulePath -> ModulePath
(ModulePath -> ModulePath -> ModulePath)
-> (NonEmpty ModulePath -> ModulePath)
-> (forall b. Integral b => b -> ModulePath -> ModulePath)
-> Semigroup ModulePath
forall b. Integral b => b -> ModulePath -> ModulePath
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: ModulePath -> ModulePath -> ModulePath
<> :: ModulePath -> ModulePath -> ModulePath
$csconcat :: NonEmpty ModulePath -> ModulePath
sconcat :: NonEmpty ModulePath -> ModulePath
$cstimes :: forall b. Integral b => b -> ModulePath -> ModulePath
stimes :: forall b. Integral b => b -> ModulePath -> ModulePath
Sem.Semigroup, Semigroup ModulePath
ModulePath
Semigroup ModulePath
-> ModulePath
-> (ModulePath -> ModulePath -> ModulePath)
-> ([ModulePath] -> ModulePath)
-> Monoid ModulePath
[ModulePath] -> ModulePath
ModulePath -> ModulePath -> ModulePath
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: ModulePath
mempty :: ModulePath
$cmappend :: ModulePath -> ModulePath -> ModulePath
mappend :: ModulePath -> ModulePath -> ModulePath
$cmconcat :: [ModulePath] -> ModulePath
mconcat :: [ModulePath] -> ModulePath
Monoid, ModulePath -> ModulePath -> Bool
(ModulePath -> ModulePath -> Bool)
-> (ModulePath -> ModulePath -> Bool) -> Eq ModulePath
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ModulePath -> ModulePath -> Bool
== :: ModulePath -> ModulePath -> Bool
$c/= :: ModulePath -> ModulePath -> Bool
/= :: ModulePath -> ModulePath -> Bool
Eq, Int -> ModulePath -> ShowS
[ModulePath] -> ShowS
ModulePath -> String
(Int -> ModulePath -> ShowS)
-> (ModulePath -> String)
-> ([ModulePath] -> ShowS)
-> Show ModulePath
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ModulePath -> ShowS
showsPrec :: Int -> ModulePath -> ShowS
$cshow :: ModulePath -> String
show :: ModulePath -> String
$cshowList :: [ModulePath] -> ShowS
showList :: [ModulePath] -> ShowS
Show, Eq ModulePath
Eq ModulePath
-> (ModulePath -> ModulePath -> Ordering)
-> (ModulePath -> ModulePath -> Bool)
-> (ModulePath -> ModulePath -> Bool)
-> (ModulePath -> ModulePath -> Bool)
-> (ModulePath -> ModulePath -> Bool)
-> (ModulePath -> ModulePath -> ModulePath)
-> (ModulePath -> ModulePath -> ModulePath)
-> Ord ModulePath
ModulePath -> ModulePath -> Bool
ModulePath -> ModulePath -> Ordering
ModulePath -> ModulePath -> ModulePath
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
$ccompare :: ModulePath -> ModulePath -> Ordering
compare :: ModulePath -> ModulePath -> Ordering
$c< :: ModulePath -> ModulePath -> Bool
< :: ModulePath -> ModulePath -> Bool
$c<= :: ModulePath -> ModulePath -> Bool
<= :: ModulePath -> ModulePath -> Bool
$c> :: ModulePath -> ModulePath -> Bool
> :: ModulePath -> ModulePath -> Bool
$c>= :: ModulePath -> ModulePath -> Bool
>= :: ModulePath -> ModulePath -> Bool
$cmax :: ModulePath -> ModulePath -> ModulePath
max :: ModulePath -> ModulePath -> ModulePath
$cmin :: ModulePath -> ModulePath -> ModulePath
min :: ModulePath -> ModulePath -> ModulePath
Ord)

-- | Construct a `ModulePath` from a `String`.
instance IsString ModulePath where
  fromString :: String -> ModulePath
fromString = Text -> ModulePath
toModulePath (Text -> ModulePath) -> (String -> Text) -> String -> ModulePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack

-- | Construct a path into the given GIR namespace. The given `Text`
-- will be split along ".".
--
-- === __Examples__
-- >>> dotModulePath (toModulePath "Foo")
-- "Foo"
--
-- >>> dotModulePath ("Foo" <> toModulePath "Bar.Baz")
-- "Foo.Bar.Baz"
--
-- >>> dotModulePath ("Foo" <> toModulePath "bar.baz")
-- "Foo.Bar.Baz"
toModulePath :: Text -> ModulePath
toModulePath :: Text -> ModulePath
toModulePath Text
p = [Text] -> ModulePath
ModulePath ((Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
ucFirst ((Char -> Bool) -> Text -> [Text]
T.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.') Text
p))

-- | Turn a module path into the corresponding dotted string. Note
-- that the implementation ensures that the module names start with a
-- capital letter.
--
-- === __Examples__
-- >>> dotModulePath ("Foo" /. "Bar" /. "Baz")
-- "Foo.Bar.Baz"
--
-- >>> dotModulePath ("foo" /. "bar" /. "baz")
-- "Foo.Bar.Baz"
dotModulePath :: ModulePath -> Text
dotModulePath :: ModulePath -> Text
dotModulePath (ModulePath [Text]
mp) = Text -> [Text] -> Text
T.intercalate Text
"." [Text]
mp

-- | Append the given component to the given module path.
--
-- === __Examples__
-- >>> dotModulePath ("Foo" /. "Bar")
-- "Foo.Bar"
(/.) :: ModulePath -> Text -> ModulePath
/. :: ModulePath -> Text -> ModulePath
(/.) ModulePath
mp Text
p = ModulePath
mp ModulePath -> ModulePath -> ModulePath
forall a. Semigroup a => a -> a -> a
<> Text -> ModulePath
toModulePath Text
p