packages feed

crypton-asn1-parse 0.9.5 → 0.9.6

raw patch · 5 files changed

+244/−208 lines, 5 filesdep −crypton-asn1-encodingdep ~basedep ~crypton-asn1-typesPVP ok

version bump matches the API change (PVP)

Dependencies removed: crypton-asn1-encoding

Dependency ranges changed: base, crypton-asn1-types

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -6,6 +6,16 @@ and this project adheres to the
 [Haskell Package Versioning Policy](https://pvp.haskell.org/).
 
+## 0.9.6
+
+* Move library modules to directory `src`.
+* Drop support for GHC < 8.8.
+* Depend on `crypton-asn1-types >= 0.3.6` and drop dependency on
+  `crypton-asn1-encoding`.
+* Re-exports module `Data.Types.ASN1` from package `crypton-asn1-types`.
+* Use `other-extensions` field in Cabal file.
+* Cabal file specifies `cabal-version: 1.22` (not `1.18`).
+
 ## 0.9.5
 
 * Rename `asn1-parse-0.9.5` package as `crypton-asn1-parse-0.9.5`.
− Data/ASN1/Parse.hs
@@ -1,164 +0,0 @@--- |
--- Module      : Data.ASN1.Parse
--- License     : BSD-style
--- Maintainer  : Vincent Hanquez <vincent@snarc.org>
--- Stability   : experimental
--- Portability : unknown
---
--- A parser combinator for ASN1 Stream.
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE CPP #-}
-module Data.ASN1.Parse
-    ( ParseASN1
-    -- * run
-    , runParseASN1State
-    , runParseASN1
-    , throwParseError
-    -- * combinators
-    , onNextContainer
-    , onNextContainerMaybe
-    , getNextContainer
-    , getNextContainerMaybe
-    , getNext
-    , getNextMaybe
-    , hasNext
-    , getObject
-    , getMany
-    ) where
-
-import Data.ASN1.Types
-import Data.ASN1.Stream
-import Control.Applicative
-import Control.Arrow (first)
-import Control.Monad (liftM2)
-#if MIN_VERSION_base(4,9,0)
-import Control.Monad.Fail
-#endif
-
-newtype ParseASN1 a = P { runP :: [ASN1] -> Either String (a, [ASN1]) }
-
-instance Functor ParseASN1 where
-    fmap f m = P (either Left (Right . first f) . runP m)
-instance Applicative ParseASN1 where
-    pure a = P $ \s -> Right (a, s)
-    (<*>) mf ma = P $ \s ->
-        case runP mf s of
-            Left err      -> Left err
-            Right (f, s2) ->
-                case runP ma s2 of
-                    Left err      -> Left err
-                    Right (a, s3) -> Right (f a, s3)
-instance Monad ParseASN1 where
-    return a    = pure a
-    (>>=) m1 m2 = P $ \s ->
-        case runP m1 s of
-            Left err      -> Left err
-            Right (a, s2) -> runP (m2 a) s2
-instance Alternative ParseASN1 where
-    empty = P $ \_ -> Left "empty Alternative"
-    (<|>) m1 m2 = P $ \s ->
-        case runP m1 s of
-            Left _        -> runP m2 s
-            Right (a, s2) -> Right (a, s2)
-#if MIN_VERSION_base(4,9,0)
-instance MonadFail ParseASN1 where
-    fail = throwParseError
-#endif
-
-get :: ParseASN1 [ASN1]
-get = P $ \stream -> Right (stream, stream)
-
-put :: [ASN1] -> ParseASN1 ()
-put stream = P $ \_ -> Right ((), stream)
-
--- | throw a parse error
-throwParseError :: String -> ParseASN1 a
-throwParseError s = P $ \_ -> Left s
-
--- | run the parse monad over a stream and returns the result and the remaining ASN1 Stream.
-runParseASN1State :: ParseASN1 a -> [ASN1] -> Either String (a,[ASN1])
-runParseASN1State f s = runP f s
-
--- | run the parse monad over a stream and returns the result.
---
--- If there's still some asn1 object in the state after calling f,
--- an error will be raised.
-runParseASN1 :: ParseASN1 a -> [ASN1] -> Either String a
-runParseASN1 f s =
-    case runP f s of
-        Left err      -> Left err
-        Right (o, []) -> Right o
-        Right (_, er) -> Left ("runParseASN1: remaining state " ++ show er)
-
--- | get next object
-getObject :: ASN1Object a => ParseASN1 a
-getObject = do
-    l <- get
-    case fromASN1 l of
-        Left err     -> throwParseError err
-        Right (a,l2) -> put l2 >> return a
-
--- | get next element from the stream
-getNext :: ParseASN1 ASN1
-getNext = do
-    list <- get
-    case list of
-        []    -> throwParseError "empty"
-        (h:l) -> put l >> return h
-
--- | get many elements until there's nothing left
-getMany :: ParseASN1 a -> ParseASN1 [a]
-getMany getOne = do
-    next <- hasNext
-    if next
-        then liftM2 (:) getOne (getMany getOne)
-        else return []
-
--- | get next element from the stream maybe
-getNextMaybe :: (ASN1 -> Maybe a) -> ParseASN1 (Maybe a)
-getNextMaybe f = do
-    list <- get
-    case list of
-        []    -> return Nothing
-        (h:l) -> let r = f h
-                  in do case r of
-                            Nothing -> put list
-                            Just _  -> put l
-                        return r
-
--- | get next container of specified type and return all its elements
-getNextContainer :: ASN1ConstructionType -> ParseASN1 [ASN1]
-getNextContainer ty = do
-    list <- get
-    case list of
-        []                    -> throwParseError "empty"
-        (h:l) | h == Start ty -> do let (l1, l2) = getConstructedEnd 0 l
-                                    put l2 >> return l1
-              | otherwise     -> throwParseError "not an expected container"
-
-
--- | run a function of the next elements of a container of specified type
-onNextContainer :: ASN1ConstructionType -> ParseASN1 a -> ParseASN1 a
-onNextContainer ty f = getNextContainer ty >>= either throwParseError return . runParseASN1 f
-
--- | just like getNextContainer, except it doesn't throw an error if the container doesn't exists.
-getNextContainerMaybe :: ASN1ConstructionType -> ParseASN1 (Maybe [ASN1])
-getNextContainerMaybe ty = do
-    list <- get
-    case list of
-        []                    -> return Nothing
-        (h:l) | h == Start ty -> do let (l1, l2) = getConstructedEnd 0 l
-                                    put l2 >> return (Just l1)
-              | otherwise     -> return Nothing
-
--- | just like onNextContainer, except it doesn't throw an error if the container doesn't exists.
-onNextContainerMaybe :: ASN1ConstructionType -> ParseASN1 a -> ParseASN1 (Maybe a)
-onNextContainerMaybe ty f = do
-    n <- getNextContainerMaybe ty
-    case n of
-        Just l  -> either throwParseError (return . Just) $ runParseASN1 f l
-        Nothing -> return Nothing
-
--- | returns if there's more elements in the stream.
-hasNext :: ParseASN1 Bool
-hasNext = not . null <$> get
README.md view
@@ -4,9 +4,8 @@ Originally forked from
 [asn1-parse-0.9.5](https://hackage.haskell.org/package/asn1-parse-0.9.5).
 
-ASN.1 for Haskell
-
-* crypton-asn1-parse : combinator based parsers for ASN.1 types.
+A library providing a monadic parser combinator for use with a stream of
+Abstract Syntax Notation One (ASN.1) standard values.
 
 History
 -------
crypton-asn1-parse.cabal view
@@ -1,41 +1,46 @@-cabal-version: 1.18
-
--- This file has been generated from package.yaml by hpack version 0.38.1.
---
--- see: https://github.com/sol/hpack
-
-name:           crypton-asn1-parse
-version:        0.9.5
-synopsis:       Simple monadic parser for ASN1 stream types.
-description:    Simple monadic parser for ASN1 stream types, when ASN1 pattern matching is not
-                convenient.
-category:       Data
-stability:      experimental
-homepage:       https://github.com/mpilgrem/crypton-asn1
-bug-reports:    https://github.com/mpilgrem/crypton-asn1/issues
-author:         Vincent Hanquez <vincent@snarc.org>
-maintainer:     Mike Pilgrem <public@pilgrem.com>,
-                Kazu Yamamoto <kazu@iij.ad.jp>
-copyright:      Vincent Hanquez <vincent@snarc.org>
-license:        BSD3
-license-file:   LICENSE
-build-type:     Simple
-extra-doc-files:
-    CHANGELOG.md
-    README.md
-
-source-repository head
-  type: git
-  location: https://github.com/mpilgrem/crypton-asn1
-  subdir: parse
-
-library
-  exposed-modules:
-      Data.ASN1.Parse
-  ghc-options: -Wall
-  build-depends:
-      base >=3 && <5
-    , bytestring
-    , crypton-asn1-encoding >=0.9
-    , crypton-asn1-types ==0.3.*
-  default-language: Haskell98
+cabal-version: 1.22
++-- This file has been generated from package.yaml by hpack version 0.38.1.+--+-- see: https://github.com/sol/hpack++name:           crypton-asn1-parse+version:        0.9.6+synopsis:       A monadic parser combinator for a ASN.1 stream.+description:    A library providing a monadic parser combinator for use with a stream of+                Abstract Syntax Notation One (ASN.1) standard values.+category:       Data+stability:      experimental+homepage:       https://github.com/mpilgrem/crypton-asn1+bug-reports:    https://github.com/mpilgrem/crypton-asn1/issues+author:         Vincent Hanquez <vincent@snarc.org>+maintainer:     Mike Pilgrem <public@pilgrem.com>,+                Kazu Yamamoto <kazu@iij.ad.jp>+copyright:      Vincent Hanquez <vincent@snarc.org>+license:        BSD3+license-file:   LICENSE+build-type:     Simple+extra-doc-files:+    CHANGELOG.md+    README.md++source-repository head+  type: git+  location: https://github.com/mpilgrem/crypton-asn1+  subdir: parse++library+  exposed-modules:+      Data.ASN1.Parse+  reexported-modules:+      Data.ASN1.Types+  hs-source-dirs:+      src+  other-extensions:+      LambdaCase+  ghc-options: -Wall+  build-depends:+      base >=4.13 && <5+    , bytestring+    , crypton-asn1-types >=0.3.6 && <0.4+  default-language: Haskell98
+ src/Data/ASN1/Parse.hs view
@@ -0,0 +1,186 @@+{-# LANGUAGE LambdaCase #-}
+
+{- |
+Module      : Data.ASN1.Parse
+License     : BSD-style
+Copyright   : (c) 2010-2013 Vincent Hanquez <vincent@snarc.org>
+Stability   : experimental
+Portability : unknown
+
+A monadic parser combinator for a stream of ASN.1 items.
+-}
+
+module Data.ASN1.Parse
+  ( ParseASN1
+    -- * Run 'ParseASN1'
+  , runParseASN1State
+  , runParseASN1
+  , throwParseError
+    -- * Combinators
+  , onNextContainer
+  , onNextContainerMaybe
+  , getNextContainer
+  , getNextContainerMaybe
+  , getNext
+  , getNextMaybe
+  , hasNext
+  , getObject
+  , getMany
+  ) where
+
+import           Control.Applicative ( Alternative (..) )
+import           Control.Arrow ( first )
+import           Control.Monad ( liftM2 )
+import           Data.ASN1.Types
+                   ( ASN1 (..), ASN1ConstructionType (..), ASN1Object (..) )
+import           Data.ASN1.Stream ( getConstructedEnd )
+
+-- | Type representing a parser combinator for a stream of ASN.1 items.
+newtype ParseASN1 a = P { runP :: [ASN1] -> Either String (a, [ASN1]) }
+
+instance Functor ParseASN1 where
+  fmap f m = P (fmap (first f) . runP m)
+
+instance Applicative ParseASN1 where
+  pure a = P $ \s -> Right (a, s)
+
+  (<*>) mf ma = P $ \s ->
+    case runP mf s of
+      Left err      -> Left err
+      Right (f, s2) ->
+        case runP ma s2 of
+          Left err      -> Left err
+          Right (a, s3) -> Right (f a, s3)
+
+instance Monad ParseASN1 where
+  return = pure
+
+  (>>=) m1 m2 = P $ \s ->
+    case runP m1 s of
+      Left err      -> Left err
+      Right (a, s2) -> runP (m2 a) s2
+
+instance Alternative ParseASN1 where
+  empty = P $ \_ -> Left "empty Alternative"
+
+  (<|>) m1 m2 = P $ \s ->
+    case runP m1 s of
+      Left _        -> runP m2 s
+      Right (a, s2) -> Right (a, s2)
+
+instance MonadFail ParseASN1 where
+  fail = throwParseError
+
+-- | Run the given parse monad over the given list of ASN.1 items. Returns the
+-- result and a list of the ASN.1 items remaining in the stream (if successful).
+runParseASN1State :: ParseASN1 a -> [ASN1] -> Either String (a, [ASN1])
+runParseASN1State = runP
+
+-- | Run the given parse monad over the given list of ASN.1 items and returns
+-- the result (if successful).
+--
+-- If ASN.1 items remain in the stream after doing so, returns an error.
+runParseASN1 :: ParseASN1 a -> [ASN1] -> Either String a
+runParseASN1 f list =
+  case runP f list of
+    Left err      -> Left err
+    Right (result, []) -> Right result
+    Right (_, rest) -> Left ("runParseASN1: remaining state " ++ show rest)
+
+-- | Throw a parse error.
+throwParseError ::
+     String
+     -- ^ Error message.
+  -> ParseASN1 a
+throwParseError err = P $ \_ -> Left err
+
+-- | Returns a list of ASN.1 items in the stream.
+get :: ParseASN1 [ASN1]
+get = P $ \list -> Right (list, list)
+
+-- | Puts the given list of ASN.1 items as the remainder of the stream and
+-- returns @()@.
+put :: [ASN1] -> ParseASN1 ()
+put list = P $ \_ -> Right ((), list)
+
+-- | Run the parse monad over the elements of the next container of specified
+-- type. Throws an error if there is no next container of the specified type.
+onNextContainer :: ASN1ConstructionType -> ParseASN1 a -> ParseASN1 a
+onNextContainer ty f =
+  getNextContainer ty >>= either throwParseError pure . runParseASN1 f
+
+-- | As for 'onNextContainer', except that it does not throw an error if there
+-- is no next container of the specified type.
+onNextContainerMaybe ::
+     ASN1ConstructionType
+  -> ParseASN1 a
+  -> ParseASN1 (Maybe a)
+onNextContainerMaybe ty f =
+  getNextContainerMaybe ty >>= \case
+    Nothing -> pure Nothing
+    Just list -> either throwParseError (pure . Just) $ runParseASN1 f list
+
+-- | Get the next container of the specified type and return a list of all its
+-- ASN.1 elements. Throws a parse error if there is no next container of the
+-- specified type.
+getNextContainer :: ASN1ConstructionType -> ParseASN1 [ASN1]
+getNextContainer ty =
+  get >>= \case
+    [] -> throwParseError "empty"
+    (item : rest)
+      | item == Start ty -> do
+          let (list, rest') = getConstructedEnd 0 rest
+          put rest' >> pure list
+      | otherwise -> throwParseError "not an expected container"
+
+-- | As for 'getNextContainer', except that it does not throw an error if there
+-- is no next container of the specified type.
+getNextContainerMaybe :: ASN1ConstructionType -> ParseASN1 (Maybe [ASN1])
+getNextContainerMaybe ty =
+  get >>= \case
+    [] -> pure Nothing
+    (item : rest)
+      | item == Start ty -> do
+          let (list, rest') = getConstructedEnd 0 rest
+          put rest' >> pure (Just list)
+      | otherwise -> pure Nothing
+
+-- | Get the next ASN.1 item in a stream of ASN.1 items.
+getNext :: ParseASN1 ASN1
+getNext =
+  get >>= \case
+    [] -> throwParseError "empty"
+    (item : rest) -> put rest >> pure item
+
+-- | Applies the given function to the next ASN.1 item in a stream of ASN.1
+-- items, if there is one.
+getNextMaybe :: (ASN1 -> Maybe a) -> ParseASN1 (Maybe a)
+getNextMaybe f =
+  get >>= \case
+    [] -> pure Nothing
+    list@(item : rest) -> do
+      let result = f item
+      case result of
+        Nothing -> put list
+        Just _  -> put rest
+      pure result
+
+-- | Are there any more ASN.1 items in the stream?
+hasNext :: ParseASN1 Bool
+hasNext = not . null <$> get
+
+-- | Get the object from the next ASN.1 item in a stream of ASN.1 items.
+-- Throws a parse error if the object cannot be obtained from the item.
+getObject :: ASN1Object a => ParseASN1 a
+getObject = do
+  list <- get
+  case fromASN1 list of
+    Left err -> throwParseError err
+    Right (object, rest) -> put rest >> pure object
+
+-- | Get many items from the stream until there are none left.
+getMany :: ParseASN1 a -> ParseASN1 [a]
+getMany getOne =
+  hasNext >>= \case
+    True -> liftM2 (:) getOne (getMany getOne)
+    False -> pure []