-- | -- Module : Data.Bitfield -- Copyright : (c) Jannis Overesch 2022-2022 -- License : MIT -- Maintainer : overesch.jannis@gmail.com -- -- Generic and easy to use bitfields. Pack and unpack records into compact representations. -- The implementation is generic over the representation and the record, however it is -- assumed that the representation is some integral type and that the record has an instance of -- 'GHC.Generics.Generic'. -- -- Due to possible overlap with the method names, it is recommended to use this module with a qualified import. -- -- @ -- import Data.Bitfield -- -- data Example = Example { one :: Bool, two :: Bool, three :: Bool, four :: Word8 } deriving (Show, Generic) -- -- x :: Bitfield Word16 Example -- x = pack $ Example True False True 4 -- -- >>> x -- Example { one = True, two = False, three = True, four = 4 } -- >>> get \@"two" x -- False -- >>> set \@"three" x False -- Example { one = True, two = False, three = False, four = 4 } -- @ -- -- The values in the bitfield will be in whatever order the 'GHC.Generics.Generic' instance defines them in. -- This is usually the order in which they are defined. -- -- Access with @OverloadedRecordDot@ is also supported: -- -- @ -- {-# LANGUAGE OverloadedRecordDot #-} -- -- import Data.Bitfield -- -- data Example = Example { one :: Bool, two :: Bool, three :: Bool } deriving (Show, Generic) -- -- x :: Bitfield Word8 Example -- x = pack $ Example True False True -- -- >>> x.one -- True -- @ -- -- 'Bitfield' supports a variety of field types as long as those implement 'HasFixedBitSize' and 'AsRep'. -- These instances are usually derived via 'GenericEnum' or 'ViaIntegral'. -- -- @ -- data AEnum = A1 | A2 | A3 -- deriving stock (Generic, Enum) -- deriving (HasFixedBitSize, AsRep r) via (GenericEnum AEnum) -- -- newtype SmallInt = SmallInt Int -- deriving (HasFixedBitSize, AsRep r) via (ViaIntegral 5 Int) -- -- data Example = Example { a :: AEnum, b :: SmallInt } -- -- x :: Bitfield Word8 Example -- x = pack $ Example A2 (SmallInt 3) -- @ -- -- It is also possible to nest 'Bitfield's, but they are not unpacked, the representation of the nested field is used directly. -- -- @ -- data Nested = Nested { a :: Bool, b :: Bool } -- data Example = Example { one :: Bitfield Word8 Nested, other :: Bool } -- -- -- This bitfield requires at least 9 bits because the field "one" requires 8 bits. -- x :: Bitfield Word16 Example -- x = Pack $ Example (pack $ Nested True True) False -- @ module Data.Bitfield ( -- * Bitfield Bitfield(Bitfield) , unwrap -- * General use , get, set , pack, unpack -- * Custom fields , HasFixedBitSize(..) , AsRep(..) , ViaIntegral(..) , GenericEnum(..) ) where import Data.Bitfield.Internal