-- |
-- Module      : Streamly.Internal.Data.Path
-- Copyright   : (c) 2023 Composewell Technologies
-- License     : BSD3
-- Maintainer  : streamly@composewell.com
-- Portability : GHC
--
module Streamly.Internal.Data.Path
    (
    -- * Exceptions
      PathException (..)

    -- * Conversions
    , IsPath (..)
    )
where

import Control.Exception (Exception)
import Control.Monad.Catch (MonadThrow(..))

------------------------------------------------------------------------------
-- Exceptions
------------------------------------------------------------------------------

-- | Exceptions thrown by path operations.
newtype PathException =
    InvalidPath String
    deriving (Int -> PathException -> ShowS
[PathException] -> ShowS
PathException -> String
(Int -> PathException -> ShowS)
-> (PathException -> String)
-> ([PathException] -> ShowS)
-> Show PathException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PathException -> ShowS
showsPrec :: Int -> PathException -> ShowS
$cshow :: PathException -> String
show :: PathException -> String
$cshowList :: [PathException] -> ShowS
showList :: [PathException] -> ShowS
Show, PathException -> PathException -> Bool
(PathException -> PathException -> Bool)
-> (PathException -> PathException -> Bool) -> Eq PathException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PathException -> PathException -> Bool
== :: PathException -> PathException -> Bool
$c/= :: PathException -> PathException -> Bool
/= :: PathException -> PathException -> Bool
Eq)

instance Exception PathException

------------------------------------------------------------------------------
-- Conversions
------------------------------------------------------------------------------

-- XXX Swap the order of IsPath arguments?
-- XXX rename to fromBase, fromBasePath, fromOsPath?

-- | If the type @a b@ is a member of 'IsPath' it means we know how to convert
-- the type @b@ to and from the base type @a@.
--
class IsPath a b where
    -- | Like 'fromPath' but does not check the properties of 'Path'. The user
    -- is responsible to maintain the invariants enforced by the type @b@
    -- otherwise surprising behavior may result.
    --
    -- This operation provides performance and simplicity when we know that the
    -- properties of the path are already verified, for example, when we get
    -- the path from the file system or from the OS APIs.
    unsafeFromPath :: a -> b

    -- | Convert a base path type to other forms of well-typed paths. It may
    -- fail if the path does not satisfy the properties of the target type.
    --
    fromPath :: MonadThrow m => a -> m b

    -- | Convert a well-typed path to the base path type. Never fails.
    toPath :: b -> a