attoparsec-path-0.0.0.1: src/Data/Attoparsec/Path.hs
module Data.Attoparsec.Path (rootPath, relFilePath, absFilePath, relDirPath, absDirPath) where
import Data.Char (isControl, isSpace)
import Data.Attoparsec.Text (Parser, char, takeWhile1)
import qualified Data.Text as T
import Control.Applicative (Alternative (..))
import Path (Path, File, Dir, Abs, Rel, (</>))
import Unsafe.Coerce (unsafeCoerce)
rootPath :: Parser (Path Abs Dir)
rootPath =
(unsafeCoerce . (:[])) <$> char '/'
chunkPath :: Parser (Path Rel File)
chunkPath =
(unsafeCoerce . T.unpack) <$> takeWhile1 (\c -> not (isControl c || isSpace c) && c /= '/')
relFilePath :: Parser (Path Rel File)
relFilePath =
let parseComplex =
(\h t -> unsafeCoerce (unsafeCoerce h ++ unsafeCoerce t))
<$> chunkPath <*> absFilePath
parseSimple = chunkPath
in parseComplex <|> parseSimple
absFilePath :: Parser (Path Abs File)
absFilePath =
(</>) <$> rootPath <*> relFilePath
relDirPath :: Parser (Path Rel Dir)
relDirPath =
(\files suffix -> unsafeCoerce (unsafeCoerce files ++ unsafeCoerce suffix))
<$> relFilePath <*> rootPath
absDirPath :: Parser (Path Abs Dir)
absDirPath =
(</>) <$> rootPath <*> relDirPath