feat: generic deriving for extraction
This commit is contained in:
parent
7a20aeeca2
commit
84510b41a5
3 changed files with 39 additions and 7 deletions
|
@ -1,6 +1,6 @@
|
||||||
{-# LANGUAGE DeriveFunctor #-}
|
{-# LANGUAGE DeriveFunctor #-}
|
||||||
{-# LANGUAGE InstanceSigs #-}
|
{-# LANGUAGE InstanceSigs #-}
|
||||||
module Language.Java.Classfile.Extract (Extract(), bytes) where
|
module Language.Java.Classfile.Extract (Extract(), bytes, runExtract) where
|
||||||
|
|
||||||
import Data.ByteString.Lazy (ByteString)
|
import Data.ByteString.Lazy (ByteString)
|
||||||
import qualified Data.ByteString.Lazy as ByteString
|
import qualified Data.ByteString.Lazy as ByteString
|
||||||
|
@ -37,7 +37,6 @@ instance Alternative Extract where
|
||||||
Fail -> right input
|
Fail -> right input
|
||||||
t -> t
|
t -> t
|
||||||
|
|
||||||
|
|
||||||
-- | Get a specified count of bytes. Fail if there are not enough bytes available.
|
-- | Get a specified count of bytes. Fail if there are not enough bytes available.
|
||||||
|
|
||||||
bytes :: Word -> Extract ByteString
|
bytes :: Word -> Extract ByteString
|
||||||
|
@ -48,7 +47,6 @@ bytes count = Extract $ \ input -> let
|
||||||
then Fail
|
then Fail
|
||||||
else Done rest bs
|
else Done rest bs
|
||||||
|
|
||||||
|
|
||||||
{- It seems I cannot define a lawful monad instance
|
{- It seems I cannot define a lawful monad instance
|
||||||
instance Monad Extract where
|
instance Monad Extract where
|
||||||
(>>=) :: Extract a -> (a -> Extract b) -> Extract b
|
(>>=) :: Extract a -> (a -> Extract b) -> Extract b
|
||||||
|
@ -57,3 +55,8 @@ instance Monad Extract where
|
||||||
Fail -> Fail
|
Fail -> Fail
|
||||||
-}
|
-}
|
||||||
|
|
||||||
|
runExtract :: ByteString -> Extract b -> Maybe (ByteString, b)
|
||||||
|
runExtract string (Extract computation) = case computation string of
|
||||||
|
Fail -> Nothing
|
||||||
|
Done rest x -> Just (rest, x)
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
{-# LANGUAGE InstanceSigs #-}
|
{-# LANGUAGE InstanceSigs #-}
|
||||||
{-# LANGUAGE TypeOperators #-}
|
{-# LANGUAGE TypeOperators #-}
|
||||||
module Language.Java.Classfile.Extractable () where
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
|
module Language.Java.Classfile.Extractable (Extractable()) where
|
||||||
|
|
||||||
import Language.Java.Classfile.Extract (Extract, bytes)
|
import Language.Java.Classfile.Extract (Extract, bytes)
|
||||||
import Data.Word (Word8, Word16, Word32)
|
import Data.Word (Word8, Word16, Word32)
|
||||||
import qualified Data.ByteString.Lazy as ByteString
|
import qualified Data.ByteString.Lazy as ByteString
|
||||||
import Data.ByteString.Lazy (ByteString)
|
import Data.ByteString.Lazy (ByteString)
|
||||||
import Data.Bits (Bits(shiftL, (.|.)))
|
import Data.Bits (Bits(shiftL, (.|.)))
|
||||||
import GHC.Generics (U1 (U1), (:*:))
|
import GHC.Generics (U1 (U1), (:*:) ((:*:)), (:+:) (L1, R1), M1 (M1), K1 (K1), Generic (Rep, to), Generically (Generically))
|
||||||
import Control.Applicative ((<|>))
|
import Control.Applicative ((<|>))
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,13 +37,32 @@ shiftOr word appendix = shiftL word 8 .|. fromIntegral appendix
|
||||||
class GenericExtractable a where
|
class GenericExtractable a where
|
||||||
genericExtract :: Extract (a i)
|
genericExtract :: Extract (a i)
|
||||||
|
|
||||||
|
-- sum types
|
||||||
|
instance (GenericExtractable l, GenericExtractable r) => GenericExtractable (l :+: r) where
|
||||||
|
genericExtract :: Extract ((:+:) l r i)
|
||||||
|
genericExtract = (L1 <$> genericExtract) <|> (R1 <$> genericExtract)
|
||||||
|
|
||||||
-- unit data types
|
-- unit data types
|
||||||
instance GenericExtractable U1 where
|
instance GenericExtractable U1 where
|
||||||
genericExtract :: Extract (U1 i)
|
genericExtract :: Extract (U1 i)
|
||||||
genericExtract = pure U1
|
genericExtract = pure U1
|
||||||
|
|
||||||
-- product types
|
-- product types
|
||||||
instance GenericExtractable (l :*: r) where
|
instance (GenericExtractable l, GenericExtractable r) => GenericExtractable (l :*: r) where
|
||||||
genericExtract :: Extract ((:*:) l r i)
|
genericExtract :: Extract ((:*:) l r i)
|
||||||
genericExtract = genericExtract <|> genericExtract
|
genericExtract = liftA2 (:*:) genericExtract genericExtract
|
||||||
|
|
||||||
|
-- meta information constructors
|
||||||
|
instance GenericExtractable a => GenericExtractable (M1 i c a) where
|
||||||
|
genericExtract :: Extract (M1 i c a i2)
|
||||||
|
genericExtract = M1 <$> genericExtract
|
||||||
|
|
||||||
|
-- fields !! yay
|
||||||
|
instance Extractable a => GenericExtractable (K1 i a) where
|
||||||
|
genericExtract :: Extract (K1 i1 a i2)
|
||||||
|
genericExtract = K1 <$> extract
|
||||||
|
|
||||||
|
instance (Generic a, GenericExtractable (Rep a)) => Extractable (Generically a) where
|
||||||
|
extract :: Extract (Generically a)
|
||||||
|
extract = Generically . to <$> genericExtract
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
|
{-# LANGUAGE DerivingStrategies #-}
|
||||||
|
{-# LANGUAGE DeriveGeneric #-}
|
||||||
|
{-# LANGUAGE DerivingVia #-}
|
||||||
module Language.Java.Classfile.Version (Version(..)) where
|
module Language.Java.Classfile.Version (Version(..)) where
|
||||||
|
|
||||||
import Data.Word (Word16)
|
import Data.Word (Word16)
|
||||||
|
import GHC.Generics (Generic, Generically(Generically))
|
||||||
|
import Language.Java.Classfile.Extractable (Extractable)
|
||||||
|
|
||||||
data Version = Version
|
data Version = Version
|
||||||
{ minor :: Word16
|
{ minor :: Word16
|
||||||
, major :: Word16
|
, major :: Word16
|
||||||
}
|
}
|
||||||
|
deriving stock (Show, Generic)
|
||||||
|
deriving Extractable via Generically Version
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue