{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoStarIsType #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveLift #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

module Data.SerDoc.Info
where

import Data.Data
import Data.Word
import Language.Haskell.TH.Syntax (Lift)

-- * Documentation annotation types

-- | Used to add descriptions via @ANN@ pragmas. This is necessary because
-- Template Haskell cannot find Haddock comments attached to constructors inside
-- associated types, but it can find annotations on those same constructors.
newtype Description = Description { Description -> [String]
descriptionParagraphs :: [String] }
  deriving newtype (Int -> Description -> ShowS
[Description] -> ShowS
Description -> String
(Int -> Description -> ShowS)
-> (Description -> String)
-> ([Description] -> ShowS)
-> Show Description
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Description -> ShowS
showsPrec :: Int -> Description -> ShowS
$cshow :: Description -> String
show :: Description -> String
$cshowList :: [Description] -> ShowS
showList :: [Description] -> ShowS
Show, ReadPrec [Description]
ReadPrec Description
Int -> ReadS Description
ReadS [Description]
(Int -> ReadS Description)
-> ReadS [Description]
-> ReadPrec Description
-> ReadPrec [Description]
-> Read Description
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Description
readsPrec :: Int -> ReadS Description
$creadList :: ReadS [Description]
readList :: ReadS [Description]
$creadPrec :: ReadPrec Description
readPrec :: ReadPrec Description
$creadListPrec :: ReadPrec [Description]
readListPrec :: ReadPrec [Description]
Read, Description -> Description -> Bool
(Description -> Description -> Bool)
-> (Description -> Description -> Bool) -> Eq Description
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Description -> Description -> Bool
== :: Description -> Description -> Bool
$c/= :: Description -> Description -> Bool
/= :: Description -> Description -> Bool
Eq, NonEmpty Description -> Description
Description -> Description -> Description
(Description -> Description -> Description)
-> (NonEmpty Description -> Description)
-> (forall b. Integral b => b -> Description -> Description)
-> Semigroup Description
forall b. Integral b => b -> Description -> Description
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: Description -> Description -> Description
<> :: Description -> Description -> Description
$csconcat :: NonEmpty Description -> Description
sconcat :: NonEmpty Description -> Description
$cstimes :: forall b. Integral b => b -> Description -> Description
stimes :: forall b. Integral b => b -> Description -> Description
Semigroup, Semigroup Description
Description
Semigroup Description =>
Description
-> (Description -> Description -> Description)
-> ([Description] -> Description)
-> Monoid Description
[Description] -> Description
Description -> Description -> Description
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: Description
mempty :: Description
$cmappend :: Description -> Description -> Description
mappend :: Description -> Description -> Description
$cmconcat :: [Description] -> Description
mconcat :: [Description] -> Description
Monoid)
  deriving (Typeable Description
Typeable Description =>
(forall (c :: Type -> Type).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Description -> c Description)
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Description)
-> (Description -> Constr)
-> (Description -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Description))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c Description))
-> ((forall b. Data b => b -> b) -> Description -> Description)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Description -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Description -> r)
-> (forall u. (forall d. Data d => d -> u) -> Description -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> Description -> u)
-> (forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> Description -> m Description)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Description -> m Description)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Description -> m Description)
-> Data Description
Description -> Constr
Description -> DataType
(forall b. Data b => b -> b) -> Description -> Description
forall a.
Typeable a =>
(forall (c :: Type -> Type).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Description -> u
forall u. (forall d. Data d => d -> u) -> Description -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Description -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Description -> r
forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> Description -> m Description
forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Description -> m Description
forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Description
forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Description -> c Description
forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Description)
forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c Description)
$cgfoldl :: forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Description -> c Description
gfoldl :: forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Description -> c Description
$cgunfold :: forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Description
gunfold :: forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Description
$ctoConstr :: Description -> Constr
toConstr :: Description -> Constr
$cdataTypeOf :: Description -> DataType
dataTypeOf :: Description -> DataType
$cdataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Description)
dataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Description)
$cdataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c Description)
dataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c Description)
$cgmapT :: (forall b. Data b => b -> b) -> Description -> Description
gmapT :: (forall b. Data b => b -> b) -> Description -> Description
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Description -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Description -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Description -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Description -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Description -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Description -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Description -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Description -> u
$cgmapM :: forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> Description -> m Description
gmapM :: forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> Description -> m Description
$cgmapMp :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Description -> m Description
gmapMp :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Description -> m Description
$cgmapMo :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Description -> m Description
gmapMo :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Description -> m Description
Data, Typeable, (forall (m :: Type -> Type). Quote m => Description -> m Exp)
-> (forall (m :: Type -> Type).
    Quote m =>
    Description -> Code m Description)
-> Lift Description
forall t.
(forall (m :: Type -> Type). Quote m => t -> m Exp)
-> (forall (m :: Type -> Type). Quote m => t -> Code m t) -> Lift t
forall (m :: Type -> Type). Quote m => Description -> m Exp
forall (m :: Type -> Type).
Quote m =>
Description -> Code m Description
$clift :: forall (m :: Type -> Type). Quote m => Description -> m Exp
lift :: forall (m :: Type -> Type). Quote m => Description -> m Exp
$cliftTyped :: forall (m :: Type -> Type).
Quote m =>
Description -> Code m Description
liftTyped :: forall (m :: Type -> Type).
Quote m =>
Description -> Code m Description
Lift)

-- * 'FieldInfo' and related types

-- | Describes the serialization format of a field.
data FieldInfo codec
  = AnnField !String !(FieldInfo codec)
    -- ^ Adds an annotation to a field.
  | BasicField !BasicFieldInfo
    -- ^ A simple field, with a named type and a size.
  | EnumField !EnumFieldInfo
    -- ^ An enum field, which reports labels and values for the possible values.
  | CompoundField !(CompoundFieldInfo codec)
    -- ^ A field that is composed out of multiple sub-fields, encoded
    -- sequentially.
  | ChoiceField !(ChoiceFieldInfo codec)
    -- ^ A list of alternatives, to be picked based on a given choice condition.
  | ListField !(ListFieldInfo codec)
    -- ^ A list of values, encoded sequentially. The length must be encoded
    -- separately, and can be referenced from a length expression.
  | AliasField !(AliasFieldInfo codec)
    -- ^ Adds an alternative name (alias) to a field type.
  | SumField !(SumFieldInfo codec)
    -- ^ A list of named alternatives. TODO: this is probably redundant and may
    -- not actually work.
  deriving (Int -> FieldInfo codec -> ShowS
[FieldInfo codec] -> ShowS
FieldInfo codec -> String
(Int -> FieldInfo codec -> ShowS)
-> (FieldInfo codec -> String)
-> ([FieldInfo codec] -> ShowS)
-> Show (FieldInfo codec)
forall codec. Int -> FieldInfo codec -> ShowS
forall codec. [FieldInfo codec] -> ShowS
forall codec. FieldInfo codec -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall codec. Int -> FieldInfo codec -> ShowS
showsPrec :: Int -> FieldInfo codec -> ShowS
$cshow :: forall codec. FieldInfo codec -> String
show :: FieldInfo codec -> String
$cshowList :: forall codec. [FieldInfo codec] -> ShowS
showList :: [FieldInfo codec] -> ShowS
Show, FieldInfo codec -> FieldInfo codec -> Bool
(FieldInfo codec -> FieldInfo codec -> Bool)
-> (FieldInfo codec -> FieldInfo codec -> Bool)
-> Eq (FieldInfo codec)
forall codec. FieldInfo codec -> FieldInfo codec -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall codec. FieldInfo codec -> FieldInfo codec -> Bool
== :: FieldInfo codec -> FieldInfo codec -> Bool
$c/= :: forall codec. FieldInfo codec -> FieldInfo codec -> Bool
/= :: FieldInfo codec -> FieldInfo codec -> Bool
Eq)

data BasicFieldInfo =
  BasicFieldInfo
    { BasicFieldInfo -> String
basicFieldType :: !String
    , BasicFieldInfo -> FieldSize
basicFieldSize :: !FieldSize
    }
  deriving (Int -> BasicFieldInfo -> ShowS
[BasicFieldInfo] -> ShowS
BasicFieldInfo -> String
(Int -> BasicFieldInfo -> ShowS)
-> (BasicFieldInfo -> String)
-> ([BasicFieldInfo] -> ShowS)
-> Show BasicFieldInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BasicFieldInfo -> ShowS
showsPrec :: Int -> BasicFieldInfo -> ShowS
$cshow :: BasicFieldInfo -> String
show :: BasicFieldInfo -> String
$cshowList :: [BasicFieldInfo] -> ShowS
showList :: [BasicFieldInfo] -> ShowS
Show, BasicFieldInfo -> BasicFieldInfo -> Bool
(BasicFieldInfo -> BasicFieldInfo -> Bool)
-> (BasicFieldInfo -> BasicFieldInfo -> Bool) -> Eq BasicFieldInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BasicFieldInfo -> BasicFieldInfo -> Bool
== :: BasicFieldInfo -> BasicFieldInfo -> Bool
$c/= :: BasicFieldInfo -> BasicFieldInfo -> Bool
/= :: BasicFieldInfo -> BasicFieldInfo -> Bool
Eq)

data EnumFieldInfo =
  EnumFieldInfo
    { EnumFieldInfo -> String
enumFieldType :: !String
    , EnumFieldInfo -> FieldSize
enumFieldSize :: !FieldSize
    , EnumFieldInfo -> [(Int, String)]
enumFieldValues :: ![(Int, String)]
    }
  deriving (Int -> EnumFieldInfo -> ShowS
[EnumFieldInfo] -> ShowS
EnumFieldInfo -> String
(Int -> EnumFieldInfo -> ShowS)
-> (EnumFieldInfo -> String)
-> ([EnumFieldInfo] -> ShowS)
-> Show EnumFieldInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EnumFieldInfo -> ShowS
showsPrec :: Int -> EnumFieldInfo -> ShowS
$cshow :: EnumFieldInfo -> String
show :: EnumFieldInfo -> String
$cshowList :: [EnumFieldInfo] -> ShowS
showList :: [EnumFieldInfo] -> ShowS
Show, EnumFieldInfo -> EnumFieldInfo -> Bool
(EnumFieldInfo -> EnumFieldInfo -> Bool)
-> (EnumFieldInfo -> EnumFieldInfo -> Bool) -> Eq EnumFieldInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EnumFieldInfo -> EnumFieldInfo -> Bool
== :: EnumFieldInfo -> EnumFieldInfo -> Bool
$c/= :: EnumFieldInfo -> EnumFieldInfo -> Bool
/= :: EnumFieldInfo -> EnumFieldInfo -> Bool
Eq)

data AliasFieldInfo codec =
  AliasFieldInfo
    { forall codec. AliasFieldInfo codec -> String
aliasFieldName :: !String
    , forall codec. AliasFieldInfo codec -> FieldInfo codec
aliasFieldTarget :: !(FieldInfo codec)
    }
  deriving (Int -> AliasFieldInfo codec -> ShowS
[AliasFieldInfo codec] -> ShowS
AliasFieldInfo codec -> String
(Int -> AliasFieldInfo codec -> ShowS)
-> (AliasFieldInfo codec -> String)
-> ([AliasFieldInfo codec] -> ShowS)
-> Show (AliasFieldInfo codec)
forall codec. Int -> AliasFieldInfo codec -> ShowS
forall codec. [AliasFieldInfo codec] -> ShowS
forall codec. AliasFieldInfo codec -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall codec. Int -> AliasFieldInfo codec -> ShowS
showsPrec :: Int -> AliasFieldInfo codec -> ShowS
$cshow :: forall codec. AliasFieldInfo codec -> String
show :: AliasFieldInfo codec -> String
$cshowList :: forall codec. [AliasFieldInfo codec] -> ShowS
showList :: [AliasFieldInfo codec] -> ShowS
Show, AliasFieldInfo codec -> AliasFieldInfo codec -> Bool
(AliasFieldInfo codec -> AliasFieldInfo codec -> Bool)
-> (AliasFieldInfo codec -> AliasFieldInfo codec -> Bool)
-> Eq (AliasFieldInfo codec)
forall codec. AliasFieldInfo codec -> AliasFieldInfo codec -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall codec. AliasFieldInfo codec -> AliasFieldInfo codec -> Bool
== :: AliasFieldInfo codec -> AliasFieldInfo codec -> Bool
$c/= :: forall codec. AliasFieldInfo codec -> AliasFieldInfo codec -> Bool
/= :: AliasFieldInfo codec -> AliasFieldInfo codec -> Bool
Eq)

data CompoundFieldInfo codec =
  CompoundFieldInfo
    { forall codec. CompoundFieldInfo codec -> String
compoundFieldType :: !String
    , forall codec. CompoundFieldInfo codec -> [SubfieldInfo codec]
compoundFieldSubfields :: ![SubfieldInfo codec]
    }
  deriving (Int -> CompoundFieldInfo codec -> ShowS
[CompoundFieldInfo codec] -> ShowS
CompoundFieldInfo codec -> String
(Int -> CompoundFieldInfo codec -> ShowS)
-> (CompoundFieldInfo codec -> String)
-> ([CompoundFieldInfo codec] -> ShowS)
-> Show (CompoundFieldInfo codec)
forall codec. Int -> CompoundFieldInfo codec -> ShowS
forall codec. [CompoundFieldInfo codec] -> ShowS
forall codec. CompoundFieldInfo codec -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall codec. Int -> CompoundFieldInfo codec -> ShowS
showsPrec :: Int -> CompoundFieldInfo codec -> ShowS
$cshow :: forall codec. CompoundFieldInfo codec -> String
show :: CompoundFieldInfo codec -> String
$cshowList :: forall codec. [CompoundFieldInfo codec] -> ShowS
showList :: [CompoundFieldInfo codec] -> ShowS
Show, CompoundFieldInfo codec -> CompoundFieldInfo codec -> Bool
(CompoundFieldInfo codec -> CompoundFieldInfo codec -> Bool)
-> (CompoundFieldInfo codec -> CompoundFieldInfo codec -> Bool)
-> Eq (CompoundFieldInfo codec)
forall codec.
CompoundFieldInfo codec -> CompoundFieldInfo codec -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall codec.
CompoundFieldInfo codec -> CompoundFieldInfo codec -> Bool
== :: CompoundFieldInfo codec -> CompoundFieldInfo codec -> Bool
$c/= :: forall codec.
CompoundFieldInfo codec -> CompoundFieldInfo codec -> Bool
/= :: CompoundFieldInfo codec -> CompoundFieldInfo codec -> Bool
Eq)

data SumFieldInfo codec =
  SumFieldInfo
    { forall codec. SumFieldInfo codec -> String
sumFieldType :: !String
    , forall codec. SumFieldInfo codec -> [(String, FieldInfo codec)]
sumFieldAlternatives :: ![(String, FieldInfo codec)]
    }
  deriving (Int -> SumFieldInfo codec -> ShowS
[SumFieldInfo codec] -> ShowS
SumFieldInfo codec -> String
(Int -> SumFieldInfo codec -> ShowS)
-> (SumFieldInfo codec -> String)
-> ([SumFieldInfo codec] -> ShowS)
-> Show (SumFieldInfo codec)
forall codec. Int -> SumFieldInfo codec -> ShowS
forall codec. [SumFieldInfo codec] -> ShowS
forall codec. SumFieldInfo codec -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall codec. Int -> SumFieldInfo codec -> ShowS
showsPrec :: Int -> SumFieldInfo codec -> ShowS
$cshow :: forall codec. SumFieldInfo codec -> String
show :: SumFieldInfo codec -> String
$cshowList :: forall codec. [SumFieldInfo codec] -> ShowS
showList :: [SumFieldInfo codec] -> ShowS
Show, SumFieldInfo codec -> SumFieldInfo codec -> Bool
(SumFieldInfo codec -> SumFieldInfo codec -> Bool)
-> (SumFieldInfo codec -> SumFieldInfo codec -> Bool)
-> Eq (SumFieldInfo codec)
forall codec. SumFieldInfo codec -> SumFieldInfo codec -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall codec. SumFieldInfo codec -> SumFieldInfo codec -> Bool
== :: SumFieldInfo codec -> SumFieldInfo codec -> Bool
$c/= :: forall codec. SumFieldInfo codec -> SumFieldInfo codec -> Bool
/= :: SumFieldInfo codec -> SumFieldInfo codec -> Bool
Eq)

data ListFieldInfo codec =
  ListFieldInfo
    { forall codec. ListFieldInfo codec -> FieldSize
listSize :: !FieldSize
    , forall codec. ListFieldInfo codec -> FieldInfo codec
listElemInfo :: !(FieldInfo codec)
    }
  deriving (Int -> ListFieldInfo codec -> ShowS
[ListFieldInfo codec] -> ShowS
ListFieldInfo codec -> String
(Int -> ListFieldInfo codec -> ShowS)
-> (ListFieldInfo codec -> String)
-> ([ListFieldInfo codec] -> ShowS)
-> Show (ListFieldInfo codec)
forall codec. Int -> ListFieldInfo codec -> ShowS
forall codec. [ListFieldInfo codec] -> ShowS
forall codec. ListFieldInfo codec -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall codec. Int -> ListFieldInfo codec -> ShowS
showsPrec :: Int -> ListFieldInfo codec -> ShowS
$cshow :: forall codec. ListFieldInfo codec -> String
show :: ListFieldInfo codec -> String
$cshowList :: forall codec. [ListFieldInfo codec] -> ShowS
showList :: [ListFieldInfo codec] -> ShowS
Show, ListFieldInfo codec -> ListFieldInfo codec -> Bool
(ListFieldInfo codec -> ListFieldInfo codec -> Bool)
-> (ListFieldInfo codec -> ListFieldInfo codec -> Bool)
-> Eq (ListFieldInfo codec)
forall codec. ListFieldInfo codec -> ListFieldInfo codec -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall codec. ListFieldInfo codec -> ListFieldInfo codec -> Bool
== :: ListFieldInfo codec -> ListFieldInfo codec -> Bool
$c/= :: forall codec. ListFieldInfo codec -> ListFieldInfo codec -> Bool
/= :: ListFieldInfo codec -> ListFieldInfo codec -> Bool
Eq)

data SubfieldInfo codec =
  SubfieldInfo
    { forall codec. SubfieldInfo codec -> String
subfieldName :: !String
    , forall codec. SubfieldInfo codec -> FieldInfo codec
subfieldInfo :: !(FieldInfo codec)
    }
  deriving (Int -> SubfieldInfo codec -> ShowS
[SubfieldInfo codec] -> ShowS
SubfieldInfo codec -> String
(Int -> SubfieldInfo codec -> ShowS)
-> (SubfieldInfo codec -> String)
-> ([SubfieldInfo codec] -> ShowS)
-> Show (SubfieldInfo codec)
forall codec. Int -> SubfieldInfo codec -> ShowS
forall codec. [SubfieldInfo codec] -> ShowS
forall codec. SubfieldInfo codec -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall codec. Int -> SubfieldInfo codec -> ShowS
showsPrec :: Int -> SubfieldInfo codec -> ShowS
$cshow :: forall codec. SubfieldInfo codec -> String
show :: SubfieldInfo codec -> String
$cshowList :: forall codec. [SubfieldInfo codec] -> ShowS
showList :: [SubfieldInfo codec] -> ShowS
Show, SubfieldInfo codec -> SubfieldInfo codec -> Bool
(SubfieldInfo codec -> SubfieldInfo codec -> Bool)
-> (SubfieldInfo codec -> SubfieldInfo codec -> Bool)
-> Eq (SubfieldInfo codec)
forall codec. SubfieldInfo codec -> SubfieldInfo codec -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall codec. SubfieldInfo codec -> SubfieldInfo codec -> Bool
== :: SubfieldInfo codec -> SubfieldInfo codec -> Bool
$c/= :: forall codec. SubfieldInfo codec -> SubfieldInfo codec -> Bool
/= :: SubfieldInfo codec -> SubfieldInfo codec -> Bool
Eq)

data ChoiceCondition
  = IndexField !String
  | IndexFlag !String Word32
  deriving (Int -> ChoiceCondition -> ShowS
[ChoiceCondition] -> ShowS
ChoiceCondition -> String
(Int -> ChoiceCondition -> ShowS)
-> (ChoiceCondition -> String)
-> ([ChoiceCondition] -> ShowS)
-> Show ChoiceCondition
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ChoiceCondition -> ShowS
showsPrec :: Int -> ChoiceCondition -> ShowS
$cshow :: ChoiceCondition -> String
show :: ChoiceCondition -> String
$cshowList :: [ChoiceCondition] -> ShowS
showList :: [ChoiceCondition] -> ShowS
Show, ChoiceCondition -> ChoiceCondition -> Bool
(ChoiceCondition -> ChoiceCondition -> Bool)
-> (ChoiceCondition -> ChoiceCondition -> Bool)
-> Eq ChoiceCondition
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ChoiceCondition -> ChoiceCondition -> Bool
== :: ChoiceCondition -> ChoiceCondition -> Bool
$c/= :: ChoiceCondition -> ChoiceCondition -> Bool
/= :: ChoiceCondition -> ChoiceCondition -> Bool
Eq)

data ChoiceFieldInfo codec =
  ChoiceFieldInfo
    { forall codec. ChoiceFieldInfo codec -> ChoiceCondition
choiceCondition :: !ChoiceCondition
    , forall codec. ChoiceFieldInfo codec -> [FieldInfo codec]
choiceFieldAlternatives :: ![FieldInfo codec]
    }
  deriving (Int -> ChoiceFieldInfo codec -> ShowS
[ChoiceFieldInfo codec] -> ShowS
ChoiceFieldInfo codec -> String
(Int -> ChoiceFieldInfo codec -> ShowS)
-> (ChoiceFieldInfo codec -> String)
-> ([ChoiceFieldInfo codec] -> ShowS)
-> Show (ChoiceFieldInfo codec)
forall codec. Int -> ChoiceFieldInfo codec -> ShowS
forall codec. [ChoiceFieldInfo codec] -> ShowS
forall codec. ChoiceFieldInfo codec -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall codec. Int -> ChoiceFieldInfo codec -> ShowS
showsPrec :: Int -> ChoiceFieldInfo codec -> ShowS
$cshow :: forall codec. ChoiceFieldInfo codec -> String
show :: ChoiceFieldInfo codec -> String
$cshowList :: forall codec. [ChoiceFieldInfo codec] -> ShowS
showList :: [ChoiceFieldInfo codec] -> ShowS
Show, ChoiceFieldInfo codec -> ChoiceFieldInfo codec -> Bool
(ChoiceFieldInfo codec -> ChoiceFieldInfo codec -> Bool)
-> (ChoiceFieldInfo codec -> ChoiceFieldInfo codec -> Bool)
-> Eq (ChoiceFieldInfo codec)
forall codec.
ChoiceFieldInfo codec -> ChoiceFieldInfo codec -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall codec.
ChoiceFieldInfo codec -> ChoiceFieldInfo codec -> Bool
== :: ChoiceFieldInfo codec -> ChoiceFieldInfo codec -> Bool
$c/= :: forall codec.
ChoiceFieldInfo codec -> ChoiceFieldInfo codec -> Bool
/= :: ChoiceFieldInfo codec -> ChoiceFieldInfo codec -> Bool
Eq)

annField :: String -> FieldInfo codec -> FieldInfo codec
annField :: forall codec. String -> FieldInfo codec -> FieldInfo codec
annField = String -> FieldInfo codec -> FieldInfo codec
forall codec. String -> FieldInfo codec -> FieldInfo codec
AnnField

basicField :: String -> FieldSize -> FieldInfo codec
basicField :: forall codec. String -> FieldSize -> FieldInfo codec
basicField String
ty FieldSize
size = BasicFieldInfo -> FieldInfo codec
forall codec. BasicFieldInfo -> FieldInfo codec
BasicField (BasicFieldInfo -> FieldInfo codec)
-> BasicFieldInfo -> FieldInfo codec
forall a b. (a -> b) -> a -> b
$ String -> FieldSize -> BasicFieldInfo
BasicFieldInfo String
ty FieldSize
size

enumField :: String -> FieldSize -> [(Int, String)] -> FieldInfo codec
enumField :: forall codec.
String -> FieldSize -> [(Int, String)] -> FieldInfo codec
enumField String
ty FieldSize
size [(Int, String)]
values = EnumFieldInfo -> FieldInfo codec
forall codec. EnumFieldInfo -> FieldInfo codec
EnumField (EnumFieldInfo -> FieldInfo codec)
-> EnumFieldInfo -> FieldInfo codec
forall a b. (a -> b) -> a -> b
$ String -> FieldSize -> [(Int, String)] -> EnumFieldInfo
EnumFieldInfo String
ty FieldSize
size [(Int, String)]
values

enumField_ :: String
           -> [String]
           -> FieldInfo codec
enumField_ :: forall codec. String -> [String] -> FieldInfo codec
enumField_ String
ty [String]
values = String -> FieldSize -> [(Int, String)] -> FieldInfo codec
forall codec.
String -> FieldSize -> [(Int, String)] -> FieldInfo codec
enumField String
ty FieldSize
EnumSize ([Int] -> [String] -> [(Int, String)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0,Int
1..] [String]
values)

aliasField :: String -> FieldInfo codec -> FieldInfo codec
aliasField :: forall codec. String -> FieldInfo codec -> FieldInfo codec
aliasField String
name FieldInfo codec
ty = AliasFieldInfo codec -> FieldInfo codec
forall codec. AliasFieldInfo codec -> FieldInfo codec
AliasField (AliasFieldInfo codec -> FieldInfo codec)
-> AliasFieldInfo codec -> FieldInfo codec
forall a b. (a -> b) -> a -> b
$ String -> FieldInfo codec -> AliasFieldInfo codec
forall codec. String -> FieldInfo codec -> AliasFieldInfo codec
AliasFieldInfo String
name FieldInfo codec
ty

compoundField :: String -> [(String, FieldInfo codec)] -> FieldInfo codec
compoundField :: forall codec.
String -> [(String, FieldInfo codec)] -> FieldInfo codec
compoundField String
ty [(String, FieldInfo codec)]
subfields =
  CompoundFieldInfo codec -> FieldInfo codec
forall codec. CompoundFieldInfo codec -> FieldInfo codec
CompoundField (CompoundFieldInfo codec -> FieldInfo codec)
-> CompoundFieldInfo codec -> FieldInfo codec
forall a b. (a -> b) -> a -> b
$
    String -> [SubfieldInfo codec] -> CompoundFieldInfo codec
forall codec.
String -> [SubfieldInfo codec] -> CompoundFieldInfo codec
CompoundFieldInfo
      String
ty
      [ String -> FieldInfo codec -> SubfieldInfo codec
forall codec. String -> FieldInfo codec -> SubfieldInfo codec
SubfieldInfo String
name FieldInfo codec
i
      | (String
name, FieldInfo codec
i) <- [(String, FieldInfo codec)]
subfields
      ]

choiceField :: ChoiceCondition -> [FieldInfo codec] -> FieldInfo codec
choiceField :: forall codec.
ChoiceCondition -> [FieldInfo codec] -> FieldInfo codec
choiceField ChoiceCondition
cond [FieldInfo codec]
subfields =
  ChoiceFieldInfo codec -> FieldInfo codec
forall codec. ChoiceFieldInfo codec -> FieldInfo codec
ChoiceField (ChoiceFieldInfo codec -> FieldInfo codec)
-> ChoiceFieldInfo codec -> FieldInfo codec
forall a b. (a -> b) -> a -> b
$
    ChoiceCondition -> [FieldInfo codec] -> ChoiceFieldInfo codec
forall codec.
ChoiceCondition -> [FieldInfo codec] -> ChoiceFieldInfo codec
ChoiceFieldInfo
      ChoiceCondition
cond
      [FieldInfo codec]
subfields

sumField :: String -> [(String, FieldInfo codec)] -> FieldInfo codec
sumField :: forall codec.
String -> [(String, FieldInfo codec)] -> FieldInfo codec
sumField String
name [(String, FieldInfo codec)]
alternatives =
  SumFieldInfo codec -> FieldInfo codec
forall codec. SumFieldInfo codec -> FieldInfo codec
SumField (SumFieldInfo codec -> FieldInfo codec)
-> SumFieldInfo codec -> FieldInfo codec
forall a b. (a -> b) -> a -> b
$
    String -> [(String, FieldInfo codec)] -> SumFieldInfo codec
forall codec.
String -> [(String, FieldInfo codec)] -> SumFieldInfo codec
SumFieldInfo
      String
name
      [(String, FieldInfo codec)]
alternatives

listField :: FieldSize -> FieldInfo codec -> FieldInfo codec
listField :: forall codec. FieldSize -> FieldInfo codec -> FieldInfo codec
listField FieldSize
lengthExpr FieldInfo codec
elemInfo =
  ListFieldInfo codec -> FieldInfo codec
forall codec. ListFieldInfo codec -> FieldInfo codec
ListField (ListFieldInfo codec -> FieldInfo codec)
-> ListFieldInfo codec -> FieldInfo codec
forall a b. (a -> b) -> a -> b
$
    FieldSize -> FieldInfo codec -> ListFieldInfo codec
forall codec. FieldSize -> FieldInfo codec -> ListFieldInfo codec
ListFieldInfo
      FieldSize
lengthExpr
      FieldInfo codec
elemInfo

-- * Field sizes

data FieldSize
  = FixedSize !Int -- ^ Exactly this size
  | EnumSize -- ^ The default enum size for the codec
  | VarSize !String -- ^ Size given by a named variable from the context
  | BinopSize !FieldSizeBinop !FieldSize !FieldSize -- ^ Binary operation
  | RangeSize !FieldSize !FieldSize -- ^ Min/max range
  | UnknownSize -- ^ Size is entirely unknown
  deriving (Int -> FieldSize -> ShowS
[FieldSize] -> ShowS
FieldSize -> String
(Int -> FieldSize -> ShowS)
-> (FieldSize -> String)
-> ([FieldSize] -> ShowS)
-> Show FieldSize
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FieldSize -> ShowS
showsPrec :: Int -> FieldSize -> ShowS
$cshow :: FieldSize -> String
show :: FieldSize -> String
$cshowList :: [FieldSize] -> ShowS
showList :: [FieldSize] -> ShowS
Show, FieldSize -> FieldSize -> Bool
(FieldSize -> FieldSize -> Bool)
-> (FieldSize -> FieldSize -> Bool) -> Eq FieldSize
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FieldSize -> FieldSize -> Bool
== :: FieldSize -> FieldSize -> Bool
$c/= :: FieldSize -> FieldSize -> Bool
/= :: FieldSize -> FieldSize -> Bool
Eq)

knownSize :: FieldSize -> Maybe Int
knownSize :: FieldSize -> Maybe Int
knownSize (FixedSize Int
i) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
i
knownSize VarSize {} = Maybe Int
forall a. Maybe a
Nothing
knownSize (BinopSize FieldSizeBinop
FSPlus FieldSize
a FieldSize
b) = Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) (Int -> Int -> Int) -> Maybe Int -> Maybe (Int -> Int)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> FieldSize -> Maybe Int
knownSize FieldSize
a Maybe (Int -> Int) -> Maybe Int -> Maybe Int
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> FieldSize -> Maybe Int
knownSize FieldSize
b
knownSize (BinopSize FieldSizeBinop
FSMul FieldSize
a FieldSize
b) = Int -> Int -> Int
forall a. Num a => a -> a -> a
(*) (Int -> Int -> Int) -> Maybe Int -> Maybe (Int -> Int)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> FieldSize -> Maybe Int
knownSize FieldSize
a Maybe (Int -> Int) -> Maybe Int -> Maybe Int
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> FieldSize -> Maybe Int
knownSize FieldSize
b
knownSize (BinopSize FieldSizeBinop
FSMax FieldSize
a FieldSize
b) = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Int -> Int -> Int) -> Maybe Int -> Maybe (Int -> Int)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> FieldSize -> Maybe Int
knownSize FieldSize
a Maybe (Int -> Int) -> Maybe Int -> Maybe Int
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> FieldSize -> Maybe Int
knownSize FieldSize
b
knownSize (BinopSize FieldSizeBinop
FSMin FieldSize
a FieldSize
b) = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Int -> Int -> Int) -> Maybe Int -> Maybe (Int -> Int)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> FieldSize -> Maybe Int
knownSize FieldSize
a Maybe (Int -> Int) -> Maybe Int -> Maybe Int
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> FieldSize -> Maybe Int
knownSize FieldSize
b
knownSize FieldSize
_ = Maybe Int
forall a. Maybe a
Nothing

data FieldSizeBinop
  = FSPlus
  | FSMul
  | FSMax
  | FSMin
  deriving (Int -> FieldSizeBinop -> ShowS
[FieldSizeBinop] -> ShowS
FieldSizeBinop -> String
(Int -> FieldSizeBinop -> ShowS)
-> (FieldSizeBinop -> String)
-> ([FieldSizeBinop] -> ShowS)
-> Show FieldSizeBinop
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FieldSizeBinop -> ShowS
showsPrec :: Int -> FieldSizeBinop -> ShowS
$cshow :: FieldSizeBinop -> String
show :: FieldSizeBinop -> String
$cshowList :: [FieldSizeBinop] -> ShowS
showList :: [FieldSizeBinop] -> ShowS
Show, FieldSizeBinop -> FieldSizeBinop -> Bool
(FieldSizeBinop -> FieldSizeBinop -> Bool)
-> (FieldSizeBinop -> FieldSizeBinop -> Bool) -> Eq FieldSizeBinop
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FieldSizeBinop -> FieldSizeBinop -> Bool
== :: FieldSizeBinop -> FieldSizeBinop -> Bool
$c/= :: FieldSizeBinop -> FieldSizeBinop -> Bool
/= :: FieldSizeBinop -> FieldSizeBinop -> Bool
Eq)