summaryrefslogtreecommitdiff
path: root/Biz/Namespace.hs
blob: 48ae1e6ef3c51e11686ba1524f5ce97653d2da75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Biz.Namespace
  ( Namespace (..),
    Ext (..),
    fromPath,
    toPath,
    toHaskellModule,
    match,
  )
where

import Alpha
import qualified Data.Char as Char
import qualified Data.List as List
import qualified Data.Text as Text
import qualified Text.Regex.Applicative as Regex

data Ext = Hs | Scm | Nix
  deriving (Show)

data Namespace = Namespace [String] Ext
  deriving (Show)

match :: String -> Maybe Namespace
match = Regex.match <| Namespace </ path <* Regex.sym '.' <*> ext
  where
    name =
      Regex.many (Regex.psym Char.isUpper)
        <> Regex.many (Regex.psym Char.isLower)
    path = Regex.many (name <* Regex.string "/" <|> name)
    ext =
      Nix <$ Regex.string "nix"
        <|> Hs <$ Regex.string "hs"
        <|> Scm <$ Regex.string "scm"

fromPath :: String -> String -> Maybe Namespace
fromPath bizRoot absPath =
  List.stripPrefix bizRoot absPath
    >>= List.stripPrefix "/"
    >>= match

toHaskellModule :: Namespace -> String
toHaskellModule (Namespace parts Hs) = joinWith "." parts
toHaskellModule (Namespace _ ext) =
  panic <| "can't convert " <> show ext <> " to a Haskell module"

toPath :: Namespace -> Text
toPath (Namespace parts ext) =
  Text.pack
    <| joinWith "/" parts
    <> "."
    <> lowercase (show ext)