module Language.Lexer.Tlex.Data.NonEmptyEnumStringSet (
    NonEmptyEnumStringSet (..),
    empty,
    insert,
    insertSingleByte,
    singleton,
    union,
    intersection,
    fromList,
) where

import           Prelude

import qualified Data.EnumMap.Strict as EnumMap
import qualified Data.EnumSet        as EnumSet
import qualified Data.List.NonEmpty  as NonEmpty


data NonEmptyEnumStringSet a = NonEmptyEnumStringSet
    { forall a. NonEmptyEnumStringSet a -> EnumSet a
singleEnums :: EnumSet.EnumSet a
    , forall a.
NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings :: EnumMap.EnumMap a (NonEmptyEnumStringSet a)
    }
    deriving (NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
forall a.
NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
$c/= :: forall a.
NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
== :: NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
$c== :: forall a.
NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> Bool
Eq, Int -> NonEmptyEnumStringSet a -> ShowS
forall a.
(Enum a, Show a) =>
Int -> NonEmptyEnumStringSet a -> ShowS
forall a. (Enum a, Show a) => [NonEmptyEnumStringSet a] -> ShowS
forall a. (Enum a, Show a) => NonEmptyEnumStringSet a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NonEmptyEnumStringSet a] -> ShowS
$cshowList :: forall a. (Enum a, Show a) => [NonEmptyEnumStringSet a] -> ShowS
show :: NonEmptyEnumStringSet a -> String
$cshow :: forall a. (Enum a, Show a) => NonEmptyEnumStringSet a -> String
showsPrec :: Int -> NonEmptyEnumStringSet a -> ShowS
$cshowsPrec :: forall a.
(Enum a, Show a) =>
Int -> NonEmptyEnumStringSet a -> ShowS
Show)

empty :: Enum a => NonEmptyEnumStringSet a
empty :: forall a. Enum a => NonEmptyEnumStringSet a
empty = NonEmptyEnumStringSet
    { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = forall k. EnumSet k
EnumSet.empty
    , $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = forall k a. EnumMap k a
EnumMap.empty
    }

singleton :: Enum a => NonEmpty.NonEmpty a -> NonEmptyEnumStringSet a
singleton :: forall a. Enum a => NonEmpty a -> NonEmptyEnumStringSet a
singleton (a
x NonEmpty.:| [a]
xs) = case [a]
xs of
    [] -> NonEmptyEnumStringSet
        { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = forall k. Enum k => k -> EnumSet k
EnumSet.singleton a
x
        , $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = forall k a. EnumMap k a
EnumMap.empty
        }
    a
y:[a]
ys -> NonEmptyEnumStringSet
        { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = forall k. EnumSet k
EnumSet.empty
        , $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = forall k a. Enum k => k -> a -> EnumMap k a
EnumMap.singleton a
x do
            forall a. Enum a => NonEmpty a -> NonEmptyEnumStringSet a
singleton do a
y forall a. a -> [a] -> NonEmpty a
NonEmpty.:| [a]
ys
        }

insert :: Enum a
    => NonEmpty.NonEmpty a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insert :: forall a.
Enum a =>
NonEmpty a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insert (a
x NonEmpty.:| [a]
xs) NonEmptyEnumStringSet a
s = case [a]
xs of
    [] -> forall a.
Enum a =>
a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insertSingleByte a
x NonEmptyEnumStringSet a
s
    a
y:[a]
ys -> let xs' :: NonEmpty a
xs' = a
y forall a. a -> [a] -> NonEmpty a
NonEmpty.:| [a]
ys in NonEmptyEnumStringSet a
s
        { $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = forall k a.
Enum k =>
(Maybe a -> Maybe a) -> k -> EnumMap k a -> EnumMap k a
EnumMap.alter
            do \case
                Maybe (NonEmptyEnumStringSet a)
Nothing  -> forall a. a -> Maybe a
Just do forall a. Enum a => NonEmpty a -> NonEmptyEnumStringSet a
singleton NonEmpty a
xs'
                Just NonEmptyEnumStringSet a
xss -> forall a. a -> Maybe a
Just do forall a.
Enum a =>
NonEmpty a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insert NonEmpty a
xs' NonEmptyEnumStringSet a
xss
            do a
x
            do forall a.
NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings NonEmptyEnumStringSet a
s
        }

insertSingleByte :: Enum a => a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insertSingleByte :: forall a.
Enum a =>
a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insertSingleByte a
x NonEmptyEnumStringSet a
s = NonEmptyEnumStringSet a
s
    { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = forall k. Enum k => k -> EnumSet k -> EnumSet k
EnumSet.insert a
x
        do forall a. NonEmptyEnumStringSet a -> EnumSet a
singleEnums NonEmptyEnumStringSet a
s
    }

union :: Enum a
    => NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
union :: forall a.
Enum a =>
NonEmptyEnumStringSet a
-> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
union NonEmptyEnumStringSet a
s1 NonEmptyEnumStringSet a
s2 = NonEmptyEnumStringSet
    { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = forall a. NonEmptyEnumStringSet a -> EnumSet a
singleEnums NonEmptyEnumStringSet a
s1 forall k. EnumSet k -> EnumSet k -> EnumSet k
`EnumSet.union` forall a. NonEmptyEnumStringSet a -> EnumSet a
singleEnums NonEmptyEnumStringSet a
s2
    , $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = forall a k.
(a -> a -> a) -> EnumMap k a -> EnumMap k a -> EnumMap k a
EnumMap.unionWith
        do \NonEmptyEnumStringSet a
xs1 NonEmptyEnumStringSet a
xs2 -> NonEmptyEnumStringSet a
xs1 forall a.
Enum a =>
NonEmptyEnumStringSet a
-> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
`union` NonEmptyEnumStringSet a
xs2
        do forall a.
NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings NonEmptyEnumStringSet a
s1
        do forall a.
NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings NonEmptyEnumStringSet a
s2
    }

intersection :: Enum a
    => NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
intersection :: forall a.
Enum a =>
NonEmptyEnumStringSet a
-> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
intersection NonEmptyEnumStringSet a
s1 NonEmptyEnumStringSet a
s2 = NonEmptyEnumStringSet
    { $sel:singleEnums:NonEmptyEnumStringSet :: EnumSet a
singleEnums = forall a. NonEmptyEnumStringSet a -> EnumSet a
singleEnums NonEmptyEnumStringSet a
s1 forall k. EnumSet k -> EnumSet k -> EnumSet k
`EnumSet.intersection` forall a. NonEmptyEnumStringSet a -> EnumSet a
singleEnums NonEmptyEnumStringSet a
s2
    , $sel:enumStrings:NonEmptyEnumStringSet :: EnumMap a (NonEmptyEnumStringSet a)
enumStrings = forall a b c k.
(a -> b -> c) -> EnumMap k a -> EnumMap k b -> EnumMap k c
EnumMap.intersectionWith
        do \NonEmptyEnumStringSet a
xs1 NonEmptyEnumStringSet a
xs2 -> NonEmptyEnumStringSet a
xs1 forall a.
Enum a =>
NonEmptyEnumStringSet a
-> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
`union` NonEmptyEnumStringSet a
xs2
        do forall a.
NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings NonEmptyEnumStringSet a
s1
        do forall a.
NonEmptyEnumStringSet a -> EnumMap a (NonEmptyEnumStringSet a)
enumStrings NonEmptyEnumStringSet a
s2
    }

fromList :: Enum a => [NonEmpty.NonEmpty a] -> NonEmptyEnumStringSet a
fromList :: forall a. Enum a => [NonEmpty a] -> NonEmptyEnumStringSet a
fromList [NonEmpty a]
xs = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall a.
Enum a =>
NonEmpty a -> NonEmptyEnumStringSet a -> NonEmptyEnumStringSet a
insert forall a. Enum a => NonEmptyEnumStringSet a
empty [NonEmpty a]
xs