------------------------------------------------------------------------------
-- |
-- Module      : LiterateX.Types.SourceFormat
-- Description : source format type
-- Copyright   : Copyright (c) 2021-2025 Travis Cardwell
-- License     : MIT
------------------------------------------------------------------------------

{-# LANGUAGE LambdaCase #-}

module LiterateX.Types.SourceFormat
  ( -- * Type
    SourceFormat(..)
    -- * API
  , describe
  , list
  ) where

-- https://hackage.haskell.org/package/ttc
import qualified Data.TTC as TTC

------------------------------------------------------------------------------
-- $Type

-- | Source format
--
-- This sum type defines the supported source formats.
--
-- @since 0.0.1.0
data SourceFormat
  = DoubleDash       -- ^ \-- comments
  | DoubleSlash      -- ^ // comments
  | Hash             -- ^ # comments
  | LispSemicolons   -- ^ Lisp semicolon comments
  | LiterateHaskell  -- ^ literate Haskell
  | Percent          -- ^ % comments
  deriving (SourceFormat
SourceFormat -> SourceFormat -> Bounded SourceFormat
forall a. a -> a -> Bounded a
$cminBound :: SourceFormat
minBound :: SourceFormat
$cmaxBound :: SourceFormat
maxBound :: SourceFormat
Bounded, Int -> SourceFormat
SourceFormat -> Int
SourceFormat -> [SourceFormat]
SourceFormat -> SourceFormat
SourceFormat -> SourceFormat -> [SourceFormat]
SourceFormat -> SourceFormat -> SourceFormat -> [SourceFormat]
(SourceFormat -> SourceFormat)
-> (SourceFormat -> SourceFormat)
-> (Int -> SourceFormat)
-> (SourceFormat -> Int)
-> (SourceFormat -> [SourceFormat])
-> (SourceFormat -> SourceFormat -> [SourceFormat])
-> (SourceFormat -> SourceFormat -> [SourceFormat])
-> (SourceFormat -> SourceFormat -> SourceFormat -> [SourceFormat])
-> Enum SourceFormat
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: SourceFormat -> SourceFormat
succ :: SourceFormat -> SourceFormat
$cpred :: SourceFormat -> SourceFormat
pred :: SourceFormat -> SourceFormat
$ctoEnum :: Int -> SourceFormat
toEnum :: Int -> SourceFormat
$cfromEnum :: SourceFormat -> Int
fromEnum :: SourceFormat -> Int
$cenumFrom :: SourceFormat -> [SourceFormat]
enumFrom :: SourceFormat -> [SourceFormat]
$cenumFromThen :: SourceFormat -> SourceFormat -> [SourceFormat]
enumFromThen :: SourceFormat -> SourceFormat -> [SourceFormat]
$cenumFromTo :: SourceFormat -> SourceFormat -> [SourceFormat]
enumFromTo :: SourceFormat -> SourceFormat -> [SourceFormat]
$cenumFromThenTo :: SourceFormat -> SourceFormat -> SourceFormat -> [SourceFormat]
enumFromThenTo :: SourceFormat -> SourceFormat -> SourceFormat -> [SourceFormat]
Enum, SourceFormat -> SourceFormat -> Bool
(SourceFormat -> SourceFormat -> Bool)
-> (SourceFormat -> SourceFormat -> Bool) -> Eq SourceFormat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SourceFormat -> SourceFormat -> Bool
== :: SourceFormat -> SourceFormat -> Bool
$c/= :: SourceFormat -> SourceFormat -> Bool
/= :: SourceFormat -> SourceFormat -> Bool
Eq, Eq SourceFormat
Eq SourceFormat =>
(SourceFormat -> SourceFormat -> Ordering)
-> (SourceFormat -> SourceFormat -> Bool)
-> (SourceFormat -> SourceFormat -> Bool)
-> (SourceFormat -> SourceFormat -> Bool)
-> (SourceFormat -> SourceFormat -> Bool)
-> (SourceFormat -> SourceFormat -> SourceFormat)
-> (SourceFormat -> SourceFormat -> SourceFormat)
-> Ord SourceFormat
SourceFormat -> SourceFormat -> Bool
SourceFormat -> SourceFormat -> Ordering
SourceFormat -> SourceFormat -> SourceFormat
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: SourceFormat -> SourceFormat -> Ordering
compare :: SourceFormat -> SourceFormat -> Ordering
$c< :: SourceFormat -> SourceFormat -> Bool
< :: SourceFormat -> SourceFormat -> Bool
$c<= :: SourceFormat -> SourceFormat -> Bool
<= :: SourceFormat -> SourceFormat -> Bool
$c> :: SourceFormat -> SourceFormat -> Bool
> :: SourceFormat -> SourceFormat -> Bool
$c>= :: SourceFormat -> SourceFormat -> Bool
>= :: SourceFormat -> SourceFormat -> Bool
$cmax :: SourceFormat -> SourceFormat -> SourceFormat
max :: SourceFormat -> SourceFormat -> SourceFormat
$cmin :: SourceFormat -> SourceFormat -> SourceFormat
min :: SourceFormat -> SourceFormat -> SourceFormat
Ord, Int -> SourceFormat -> ShowS
[SourceFormat] -> ShowS
SourceFormat -> [Char]
(Int -> SourceFormat -> ShowS)
-> (SourceFormat -> [Char])
-> ([SourceFormat] -> ShowS)
-> Show SourceFormat
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SourceFormat -> ShowS
showsPrec :: Int -> SourceFormat -> ShowS
$cshow :: SourceFormat -> [Char]
show :: SourceFormat -> [Char]
$cshowList :: [SourceFormat] -> ShowS
showList :: [SourceFormat] -> ShowS
Show)

instance TTC.Parse SourceFormat where
  parse :: forall t e. (Textual t, Textual e) => t -> Either e SourceFormat
parse = [Char] -> Bool -> Bool -> t -> Either e SourceFormat
forall t e a.
(Bounded a, Enum a, Render a, Textual t, Textual e) =>
[Char] -> Bool -> Bool -> t -> Either e a
TTC.parseEnum' [Char]
"source format" Bool
True Bool
False

instance TTC.Render SourceFormat where
  render :: forall t. Textual t => SourceFormat -> t
render = [Char] -> t
forall t. Textual t => [Char] -> t
TTC.fromS ([Char] -> t) -> (SourceFormat -> [Char]) -> SourceFormat -> t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
    SourceFormat
DoubleDash      -> [Char]
"ddash"
    SourceFormat
DoubleSlash     -> [Char]
"dslash"
    SourceFormat
Hash            -> [Char]
"hash"
    SourceFormat
LispSemicolons  -> [Char]
"lisp"
    SourceFormat
LiterateHaskell -> [Char]
"lhs"
    SourceFormat
Percent         -> [Char]
"percent"

------------------------------------------------------------------------------
-- $API

-- | Get a description of a source format
--
-- @since 0.0.1.0
describe :: SourceFormat -> String
describe :: SourceFormat -> [Char]
describe = \case
    SourceFormat
DoubleDash      -> [Char]
"-- comments"
    SourceFormat
DoubleSlash     -> [Char]
"// comments"
    SourceFormat
Hash            -> [Char]
"# comments"
    SourceFormat
LispSemicolons  -> [Char]
"Lisp semicolon comments"
    SourceFormat
LiterateHaskell -> [Char]
"literate Haskell"
    SourceFormat
Percent         -> [Char]
"% comments"

------------------------------------------------------------------------------

-- | List of all supported source formats
--
-- @since 0.0.1.0
list :: [SourceFormat]
list :: [SourceFormat]
list = [SourceFormat
forall a. Bounded a => a
minBound ..]