{-# LANGUAGE DeriveDataTypeable #-}

-- | Internal types and functions.

module HPath.Internal
  (Path(..))
  where

import Control.DeepSeq (NFData (..))
import Data.ByteString (ByteString)
import Data.Data

-- | The main Path type.
--
-- The type variable 'b' is either:
--
--   * 'HPath.Abs' -- absolute path (starting with a @"/"@)
--   * 'HPath.Rel' -- relative path (not starting with a @"/"@)
--
-- Internally it is a ByteString. The path is guaranteed to
-- be normalised and contain no trailing Path separators,
-- except for the @"/"@ root path.
--
-- There are no duplicate path separators
-- @"\/\/"@, no @".."@, no @".\/"@, etc.
-- 
-- Two special paths exist:
--
--  * @"/"@ -- the 'HPath.rootPath' (absolute)
--  * @"."@ -- the 'HPath.pwdPath' (relative)
--
-- The constructor is not exposed. Instead, use the smart constructors
-- 'HPath.parseAbs', 'HPath.parseRel' and 'HPath.parseAny'.
data Path b = MkPath ByteString
  deriving (Typeable)

-- | ByteString equality.
--
-- The following property holds:
--
-- @show x == show y ≡ x == y@
instance Eq (Path b) where
  == :: Path b -> Path b -> Bool
(==) (MkPath ByteString
x) (MkPath ByteString
y) = ByteString
x ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
y

-- | ByteString ordering.
--
-- The following property holds:
--
-- @show x \`compare\` show y ≡ x \`compare\` y@
instance Ord (Path b) where
  compare :: Path b -> Path b -> Ordering
compare (MkPath ByteString
x) (MkPath ByteString
y) = ByteString -> ByteString -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ByteString
x ByteString
y

-- | Same as 'HPath.toFilePath'.
--
-- The following property holds:
--
-- @x == y ≡ show x == show y@
instance Show (Path b) where
  show :: Path b -> String
show (MkPath ByteString
x) = ByteString -> String
forall a. Show a => a -> String
show ByteString
x

instance NFData (Path b) where
  rnf :: Path b -> ()
rnf (MkPath ByteString
x) = ByteString -> ()
forall a. NFData a => a -> ()
rnf ByteString
x