{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
module System.Filesystem.PathComponent
 ( PathComponent
 , pathComponent
 , isPathComponent
 , getPC
 , slashify
 , splitPathComponents
 ) where
import           Control.Monad.Fail
import qualified Data.ByteString       as B
import           Data.Maybe (fromMaybe)
import           Data.Semigroup
import           Data.String
import           Prelude hiding (fail)
import           System.Posix.FilePath
import           Text.Printf
newtype PathComponent = PC {
    getPC :: B.ByteString 
  } deriving (Eq, Ord, Show, Semigroup)
instance IsString PathComponent where
  fromString = fromMaybe (error "not a PathComponent") . pathComponent . fromString
pathComponent :: MonadFail m => B.ByteString -> m PathComponent
pathComponent b | isPathComponent b = pure (PC b)
                | otherwise         = fail (printf "Not a valud PathComponent (%s)" (show b))
isPathComponent :: B.ByteString -> Bool
isPathComponent "" = False
isPathComponent b  = B.all (`B.notElem` "\x00/") b
slashify :: PathComponent -> B.ByteString
slashify (PC p) = B.snoc p 0x2f
splitPathComponents :: MonadFail m => RawFilePath -> m [PathComponent]
splitPathComponents =
  
  
  
  
  maybe (fail "path contained a null byte") pure . mapM pathComponent . splitDirectories