    -- | Parsing of Enums.
    module Data.GI.GIR.Enum
        ( Enumeration(..)
        , EnumerationMember(..)
        , parseEnum
        ) where

    import Data.Int (Int64)
    import Data.Text (Text)
    import Foreign.C (CInt(..))

    import Data.GI.GIR.Parser
    import Data.GI.GIR.Type (parseCType)

    data Enumeration = Enumeration {
        Enumeration -> [EnumerationMember]
    enumMembers :: [EnumerationMember],
        Enumeration -> Maybe ParseError
    enumErrorDomain :: Maybe Text,
        Enumeration -> Maybe ParseError
    enumTypeInit :: Maybe Text,
        Enumeration -> Documentation
    enumDocumentation :: Documentation,
        Enumeration -> ParseError
    enumCType    :: Text,
        Enumeration -> Int
    enumStorageBytes :: Int, -- ^ Bytes used for storage of this struct.
        Enumeration -> Maybe DeprecationInfo
    enumDeprecated :: Maybe DeprecationInfo }
        deriving Int -> Enumeration -> ShowS
    [Enumeration] -> ShowS
    Enumeration -> String
    (Int -> Enumeration -> ShowS)
    -> (Enumeration -> String)
    -> ([Enumeration] -> ShowS)
    -> Show Enumeration
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Enumeration -> ShowS
    showsPrec :: Int -> Enumeration -> ShowS
    $cshow :: Enumeration -> String
    show :: Enumeration -> String
    $cshowList :: [Enumeration] -> ShowS
    showList :: [Enumeration] -> ShowS
    Show

    -- | Member of an enumeration.
    data EnumerationMember = EnumerationMember {
      EnumerationMember -> ParseError
    enumMemberName   :: Text,
      EnumerationMember -> Int64
    enumMemberValue  :: Int64,
      EnumerationMember -> ParseError
    enumMemberCId    :: Text,
      EnumerationMember -> Documentation
    enumMemberDoc    :: Documentation
      } deriving Int -> EnumerationMember -> ShowS
    [EnumerationMember] -> ShowS
    EnumerationMember -> String
    (Int -> EnumerationMember -> ShowS)
    -> (EnumerationMember -> String)
    -> ([EnumerationMember] -> ShowS)
    -> Show EnumerationMember
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> EnumerationMember -> ShowS
    showsPrec :: Int -> EnumerationMember -> ShowS
    $cshow :: EnumerationMember -> String
    show :: EnumerationMember -> String
    $cshowList :: [EnumerationMember] -> ShowS
    showList :: [EnumerationMember] -> ShowS
    Show

    -- | Parse a struct member.
    parseEnumMember :: Parser EnumerationMember
    parseEnumMember :: Parser EnumerationMember
    parseEnumMember = do
      name <- Name -> Parser ParseError
    getAttr Name
    "name"
      value <- getAttr "value" >>= parseIntegral
      cid <- getAttrWithNamespace CGIRNS "identifier"
      doc <- parseDocumentation
      return $ EnumerationMember {
        enumMemberName = name,
        enumMemberValue = value,
        enumMemberCId = cid,
        enumMemberDoc = doc
        }

    foreign import ccall "_gi_get_enum_storage_bytes" get_storage_bytes ::
        Int64 -> Int64 -> CInt

    -- | Return the number of bytes that should be allocated for storage
    -- of the given values in an enum.
    extractEnumStorageBytes :: [Int64] -> Int
    extractEnumStorageBytes :: [Int64] -> Int
    extractEnumStorageBytes [Int64]
    values =
        CInt -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (CInt -> Int) -> CInt -> Int
    forall a b. (a -> b) -> a -> b
    $ Int64 -> Int64 -> CInt
    get_storage_bytes ([Int64] -> Int64
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    minimum [Int64]
    values) ([Int64] -> Int64
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum [Int64]
    values)

    -- | Parse an "enumeration" element from the GIR file.
    parseEnum :: Parser (Name, Enumeration)
    parseEnum :: Parser (Name, Enumeration)
    parseEnum = do
      name <- Parser Name
    parseName
      ctype <- parseCType
      doc <- parseDocumentation
      deprecated <- parseDeprecation
      errorDomain <- queryAttrWithNamespace GLibGIRNS "error-domain"
      typeInit <- queryAttrWithNamespace GLibGIRNS "get-type"
      members <- parseChildrenWithLocalName "member" parseEnumMember
      return (name,
              Enumeration {
                enumMembers = members
              , enumErrorDomain = errorDomain
              , enumDocumentation = doc
              , enumTypeInit = typeInit
              , enumCType = ctype
              , enumStorageBytes = extractEnumStorageBytes (map enumMemberValue members)
              , enumDeprecated = deprecated
              })