{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.Git.Formats (
SafeString()
, safeString
, getSS
, LfFree
, lfFree
, isLfFree
, getLfFree
, module System.Filesystem.PathComponent
) 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.Filesystem.PathComponent
newtype SafeString = SS {
getSS :: B.ByteString
} deriving (Eq, Ord, Show, Semigroup, Monoid)
instance IsString SafeString where
fromString = fromMaybe (error "Not a SafeString.") . safeString . fromString
safeString :: MonadFail m => B.ByteString -> m SafeString
safeString b | isSafeString b = pure (SS b)
| otherwise = fail "Not a valid SafeString."
isSafeString :: B.ByteString -> Bool
isSafeString "" = True
isSafeString b = safe (B.head b) && safe (B.last b) && safeInBetween
where safe = (`B.notElem` " .,:;<>\"'")
safeInBetween = B.any (`B.notElem` "<>\x0a\x00") b
newtype LfFree = LfFree {
getLfFree :: B.ByteString
} deriving (Eq, Ord, Show, Monoid, Semigroup)
instance IsString LfFree where
fromString = fromMaybe (error "Not a LfFree, contains a linefeed.") . lfFree . fromString
isLfFree :: B.ByteString -> Bool
isLfFree = B.notElem 0x0a
lfFree :: MonadFail m => B.ByteString -> m LfFree
lfFree b | isLfFree b = pure (LfFree b)
| otherwise = fail "Not a valid LfFree; contains a linefeed."