packages feed

yaml-unscrambler 0.1.0.17 → 0.1.0.18

raw patch · 8 files changed

+210/−155 lines, 8 filesdep ~bytestringdep ~containersPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: bytestring, containers

API changes (from Hackage documentation)

Files

library/YamlUnscrambler.hs view
@@ -115,12 +115,14 @@  -- * -- +-- | Parser of any kind of YAML value: scalar, mapping or sequence. data Value a = Value   { valueExpectation :: Ex.Value,     valueParser :: Yaml.YamlValue -> Yaml.AnchorMap -> Either Err.ErrAtPath a   }   deriving (Functor) +-- | Specification of various alternative ways of parsing a non-nullable value. value :: [Scalar a] -> Maybe (Mapping a) -> Maybe (Sequence a) -> Value a value scalars mappings sequences =   Value expectations parse@@ -165,6 +167,7 @@             Nothing ->               Left (Err.ErrAtPath [] (Err.UnknownAnchorErr (fromString anchorName))) +-- | Specification of various alternative ways of parsing a nullable value. nullableValue :: [Scalar a] -> Maybe (Mapping a) -> Maybe (Sequence a) -> Value (Maybe a) nullableValue scalars mappings sequences =   value@@ -174,35 +177,43 @@  -- ** Helpers +-- | Value parser, which only expects sequence values. sequenceValue :: Sequence a -> Value a sequenceValue sequence =   value [] Nothing (Just sequence) +-- | Value parser, which only expects mapping values. mappingValue :: Mapping a -> Value a mappingValue mapping =   value [] (Just mapping) Nothing +-- | Value parser, which only expects scalar values. scalarsValue :: [Scalar a] -> Value a scalarsValue scalars =   value scalars Nothing Nothing  -- * -- +-- | Scalar value parser. data Scalar a = Scalar   { scalarExpectation :: Ex.Scalar,     scalarParser :: ByteString -> Libyaml.Tag -> Libyaml.Style -> Either Text a   }   deriving (Functor) +-- | Custom parser function of a strict bytestring as a scalar value. bytesParsingScalar :: Ex.Scalar -> (ByteString -> Either Text a) -> Scalar a bytesParsingScalar expectation parser =   Scalar expectation (\bytes _ _ -> parser bytes) +-- | Custom ASCII attoparsec parser of a scalar value. attoparsedScalar :: Ex.Scalar -> AsciiAtto.Parser a -> Scalar a attoparsedScalar expectation parser =-  bytesParsingScalar expectation $-    first (const "") . AsciiAtto.parseOnly (parser <* AsciiAtto.endOfInput)+  bytesParsingScalar expectation+    $ first (const "")+    . AsciiAtto.parseOnly (parser <* AsciiAtto.endOfInput) +-- | Add protection on the maximum allowed input size over a scalar parser. sizedScalar :: MaxInputSize -> Scalar a -> Scalar a sizedScalar (MaxInputSize maxInputSize) (Scalar {..}) =   Scalar scalarExpectation $ \bytes tag style ->@@ -210,22 +221,27 @@       then scalarParser bytes tag style       else Left ("Input is longer then the expected maximum of " <> showAsText maxInputSize <> " bytes") +-- | String scalar parser. stringScalar :: String a -> Scalar a stringScalar (String exp parse) =   bytesParsingScalar     (Ex.StringScalar exp)     (\bytes -> first showAsText (Text.decodeUtf8' bytes) >>= parse) +-- | A parser expecting a null value and resulting in the provided constant value when successful. nullScalar :: a -> Scalar a nullScalar a =   Scalar Ex.NullScalar $ \bytes tag _ ->-    if tag == Libyaml.NullTag+    if tag+      == Libyaml.NullTag       || ByteString.null bytes-      || bytes == "~"+      || bytes+      == "~"       || ByteString.saysNullInCiAscii bytes       then Right a       else Left "Not null" +-- | Boolean scalar parser. boolScalar :: Scalar Bool boolScalar =   bytesParsingScalar Ex.BoolScalar $ \bytes ->@@ -241,42 +257,52 @@                   else Left "Not a boolean"       else Left "Not a boolean" +-- | Numeric scalar as scientific parser. scientificScalar :: Scalar Scientific scientificScalar =   attoparsedScalar Ex.ScientificScalar AsciiAtto.scientific +-- | Numeric scalar as double parser. doubleScalar :: Scalar Double doubleScalar =   attoparsedScalar Ex.DoubleScalar AsciiAtto.double +-- | Numeric scalar as rational parser protected with maximum allowed input size. rationalScalar :: MaxInputSize -> Scalar Rational rationalScalar a =-  sizedScalar a $-    attoparsedScalar (Ex.RationalScalar a) AsciiAtto.rational+  sizedScalar a+    $ attoparsedScalar (Ex.RationalScalar a) AsciiAtto.rational  -- |+-- Numeric scalar parser into a bounded integer value. -- E.g., 'Int', 'Int64', 'Word', but not 'Integer'. boundedIntegerScalar :: (Integral a, FiniteBits a) => Signed -> NumeralSystem -> Scalar a boundedIntegerScalar a b =   attoparsedScalar (Ex.BoundedIntegerScalar a b) (AsciiAtto.integralScalar a b) +-- |+-- Numeric scalar parser into any integer value. unboundedIntegerScalar :: MaxInputSize -> Signed -> NumeralSystem -> Scalar Integer unboundedIntegerScalar a b c =-  sizedScalar a $-    attoparsedScalar (Ex.UnboundedIntegerScalar a b c) (AsciiAtto.integralScalar b c)+  sizedScalar a+    $ attoparsedScalar (Ex.UnboundedIntegerScalar a b c) (AsciiAtto.integralScalar b c) +-- | String scalar parser as 'UTCTime' in ISO-8601. timestampScalar :: Scalar UTCTime timestampScalar =   attoparsedScalar Ex.Iso8601TimestampScalar AsciiAtto.utcTimeInISO8601 +-- | String scalar parser as 'Day' in ISO-8601. dayScalar :: Scalar Day dayScalar =   attoparsedScalar Ex.Iso8601DayScalar AsciiAtto.dayInISO8601 +-- | String scalar parser as 'TimeOfDay' in ISO-8601. timeScalar :: Scalar TimeOfDay timeScalar =   attoparsedScalar Ex.Iso8601TimeScalar AsciiAtto.timeOfDayInISO8601 +-- | String scalar parser as 'UUID'. uuidScalar :: Scalar UUID uuidScalar =   bytesParsingScalar Ex.UuidScalar $ \bytes ->@@ -286,6 +312,7 @@       Nothing ->         Left "Invalid UUID" +-- | String scalar parser as binary data encoded in Base-64. binaryScalar :: Scalar ByteString binaryScalar =   bytesParsingScalar Ex.Base64BinaryScalar $ \bytes ->@@ -299,12 +326,14 @@  -- * -- +-- | Mapping value parser. data Mapping a = Mapping   { mappingExpectation :: Ex.Mapping,     mappingParser :: [(Text, Yaml.YamlValue)] -> Yaml.AnchorMap -> Either Err.ErrAtPath a   }   deriving (Functor) +-- | Mapping parser which folds pairs into some final data-structure. foldMapping :: (key -> val -> assoc) -> Fold assoc a -> String key -> Value val -> Mapping a foldMapping zip (Fold foldStep foldInit foldExtract) key val =   Mapping@@ -325,6 +354,7 @@               Err.ErrAtPath []                 . Err.KeyErr (stringExpectation key) keyInput +-- | Mapping parser which allows the user to look up fields and process them with individual parsers. byKeyMapping :: CaseSensitive -> ByKey Text a -> Mapping a byKeyMapping caseSensitive byKey =   Mapping expectation parser@@ -353,20 +383,22 @@                     HashMap.lookupFirst (fmap Text.toLower kl) map                in byKeyParser byKey id lookup lookupFirst         keysErr keys =-          Err.ErrAtPath [] $-            Err.NoneOfMappingKeysFoundErr (byKeyExpectation byKey) caseSensitive keysAvail (toList keys)+          Err.ErrAtPath []+            $ Err.NoneOfMappingKeysFoundErr (byKeyExpectation byKey) caseSensitive keysAvail (toList keys)           where             keysAvail =               fmap fst input  -- * -- +-- | Sequence value parser. data Sequence a = Sequence   { sequenceExpectation :: Ex.Sequence,     sequenceParser :: [Yaml.YamlValue] -> Yaml.AnchorMap -> Either Err.ErrAtPath a   }   deriving (Functor) +-- | Homogenous sequence parser which folds into a final data-structure. foldSequence :: Fold a b -> Value a -> Sequence b foldSequence (Fold foldStep foldInit foldExtract) value =   Sequence@@ -382,6 +414,7 @@             & first (Err.atSegment (showAsText index))             & fmap (\a -> (succ index, foldStep state a)) +-- | Heterogenous sequence parser by order in the sequence, which lets you apply individual parsers to elements. byOrderSequence :: ByOrder a -> Sequence a byOrderSequence (ByOrder {..}) =   Sequence@@ -395,9 +428,10 @@         mapErr =           \case             NotEnoughElementsByOrderErr a ->-              Err.ErrAtPath [] $-                Err.NotEnoughElementsErr byOrderExpectation a+              Err.ErrAtPath []+                $ Err.NotEnoughElementsErr byOrderExpectation a +-- | Heterogenous sequence parser by index in the sequence, which lets you apply individual parsers to elements. byKeySequence :: ByKey Int a -> Sequence a byKeySequence (ByKey {..}) =   Sequence expectation parser@@ -416,21 +450,24 @@               & either Left (first keysErr)       where         keysErr keys =-          Err.ErrAtPath [] $-            Err.NoneOfSequenceKeysFoundErr byKeyExpectation (toList keys)+          Err.ErrAtPath []+            $ Err.NoneOfSequenceKeysFoundErr byKeyExpectation (toList keys)  -- * -- +-- | String value parser applicable to string scalars and mapping keys. data String a = String   { stringExpectation :: Ex.String,     stringParser :: Text -> Either Text a   }   deriving (Functor) +-- | String as is. textString :: String Text textString =   String Ex.AnyString return +-- | Look the string up as a key in the provided dictionary. enumString :: CaseSensitive -> [(Text, a)] -> String a enumString (CaseSensitive caseSensitive) assocList =   String expectation parser@@ -459,13 +496,23 @@         Just a -> return a         _ -> Left "Unexpected value" -formattedString :: Text -> (Text -> Either Text a) -> String a+-- | String parsed using the provided function.+formattedString ::+  -- | Format name for documentation and expectations.+  Text ->+  (Text -> Either Text a) ->+  String a formattedString format parser =   String     (Ex.FormattedString format)     parser -attoparsedString :: Text -> TextAtto.Parser a -> String a+-- | String parsed using the provided textual attoparsec parser.+attoparsedString ::+  -- | Format name for documentation and expectations.+  Text ->+  TextAtto.Parser a ->+  String a attoparsedString format parser =   String     (Ex.FormattedString format)@@ -473,6 +520,7 @@  -- * -- +-- | General abstraction for specification of parsers performing lookups by keys. data ByKey key a = ByKey   { byKeyExpectation :: Ex.ByKey key,     byKeyParser ::@@ -508,6 +556,7 @@       (Ex.EitherByKey le re)       (\a b c d -> lp a b c d <|> rp a b c d) +-- | Parse a value at a key using the provided parser. atByKey :: key -> Value a -> ByKey key a atByKey key valueSpec =   ByKey@@ -517,12 +566,13 @@     parser renderKey lookup _ env =       case lookup key of         Just val ->-          lift $-            first (Err.atSegment (renderKey key)) $-              valueParser valueSpec val env+          lift+            $ first (Err.atSegment (renderKey key))+            $ valueParser valueSpec val env         Nothing ->           throwE (pure key) +-- | Parse a value at one of keys (whichever exists) using the provided parser. atOneOfByKey :: [key] -> Value a -> ByKey key a atOneOfByKey keys valueSpec =   ByKey@@ -532,9 +582,9 @@     parser renderKey _ lookup env =       case lookup keys of         Just (key, val) ->-          lift $-            first (Err.atSegment (renderKey key)) $-              valueParser valueSpec val env+          lift+            $ first (Err.atSegment (renderKey key))+            $ valueParser valueSpec val env         Nothing ->           throwE (fromList keys) @@ -544,6 +594,7 @@   = NotEnoughElementsByOrderErr       Int +-- | Parser which fetches elements by the order in which it is composed. data ByOrder a = ByOrder   { byOrderExpectation :: Ex.ByOrder,     byOrderParser :: StateT (Int, [Yaml.YamlValue]) (ReaderT Yaml.AnchorMap (ExceptT ByOrderErr (Either Err.ErrAtPath))) a@@ -564,6 +615,7 @@       (Ex.BothByOrder le re)       (select lp rp) +-- | Parse the next value using the provided parser. fetchByOrder :: Value a -> ByOrder a fetchByOrder value =   ByOrder
library/YamlUnscrambler/Err.hs view
@@ -25,33 +25,33 @@  data Err   = KeyErr+      -- | Key expectation.       Ex.String-      -- ^ Key expectation.+      -- | Key input.       Text-      -- ^ Key input.+      -- | String parsing error.       Text-      -- ^ String parsing error.   | NoneOfMappingKeysFoundErr       (Ex.ByKey Text)       CaseSensitive+      -- | Available keys.       [Text]-      -- ^ Available keys.+      -- | Keys looked up.       [Text]-      -- ^ Keys looked up.   | NoneOfSequenceKeysFoundErr       (Ex.ByKey Int)       [Int]   | ScalarErr+      -- | Expected formats.       [Ex.Scalar]-      -- ^ Expected formats.+      -- | Input.       ByteString-      -- ^ Input.+      -- | Tag.       Libyaml.Tag-      -- ^ Tag.+      -- | Style.       Libyaml.Style-      -- ^ Style.+      -- | Last error.       (Maybe Text)-      -- ^ Last error.   | UnexpectedScalarErr       Ex.Value   | UnexpectedMappingErr
library/YamlUnscrambler/Expectations.hs view
@@ -59,12 +59,12 @@   | -- | One of options. Suitable for enumerations.     OneOfString       CaseSensitive+      -- | Options.       [Text]-      -- ^ Options.   | -- | Must conform to a textually described format.     FormattedString+      -- | Description of the format.       Text-      -- ^ Description of the format.  data ByKey key   = AnyByKey@@ -72,8 +72,8 @@   | EitherByKey (ByKey key) (ByKey key)   | BothByKey (ByKey key) (ByKey key)   | LookupByKey+      -- | Keys to lookup.       [key]-      -- ^ Keys to lookup.       Value  data ByOrder
library/YamlUnscrambler/Prelude.hs view
@@ -1,3 +1,5 @@+{-# OPTIONS_GHC -Wno-dodgy-imports #-}+ module YamlUnscrambler.Prelude   ( module Exports,     showAsText,@@ -41,7 +43,7 @@ import Data.Fixed as Exports import Data.Foldable as Exports hiding (toList) import Data.Function as Exports hiding (id, (.))-import Data.Functor as Exports+import Data.Functor as Exports hiding (unzip) import Data.Functor.Compose as Exports import Data.HashMap.Strict as Exports (HashMap) import Data.HashSet as Exports (HashSet)@@ -90,7 +92,6 @@ import System.Mem as Exports import System.Mem.StableName as Exports import System.Timeout as Exports-import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readP_to_Prec, readPrec_to_P, readPrec_to_S, readS_to_Prec) import Text.Printf as Exports (hPrintf, printf) import Text.Read as Exports (Read (..), readEither, readMaybe) import Unsafe.Coerce as Exports
library/YamlUnscrambler/Util/Word8.hs view
@@ -4,8 +4,6 @@  lowercaseInAscii :: Word8 -> Word8 lowercaseInAscii a =-  if 65 <= a && a <= 90-    || 192 <= a && a <= 214-    || 216 <= a && a <= 222+  if 65 <= a && a <= 90 || 192 <= a && a <= 214 || 216 <= a && a <= 222     then a + 32     else a
library/YamlUnscrambler/Util/Yaml.hs view
@@ -7,8 +7,8 @@  parseByteStringToRawDoc :: ByteString -> Either Text YamlParser.RawDoc parseByteStringToRawDoc input =-  first (mappend "YAML AST parsing: " . showAsText) $-    unsafePerformIO $-      try @SomeException $-        Conduit.runConduitRes $-          Conduit.fuse (Libyaml.decode input) (YamlParser.sinkRawDoc)+  first (mappend "YAML AST parsing: " . showAsText)+    $ unsafePerformIO+    $ try @SomeException+    $ Conduit.runConduitRes+    $ Conduit.fuse (Libyaml.decode input) (YamlParser.sinkRawDoc)
test/Main.hs view
@@ -11,62 +11,62 @@  main :: IO () main =-  defaultMain $-    testGroup+  defaultMain+    $ testGroup       "All tests"-      [ testCase "Should fail on sequence when no sequence is specified" $-          let unscrambler =-                U.value [] (Just mapping) Nothing-                where-                  mapping =-                    U.foldMapping (,) Fold.list U.textString value-                    where-                      value =-                        U.value [nullScalar, intScalar] Nothing Nothing-                        where-                          nullScalar =-                            U.nullScalar Nothing-                          intScalar =-                            fmap Just $ U.boundedIntegerScalar @Int (U.Signed True) U.DecimalNumeralSystem-              input =-                [NeatInterpolation.text|+      [ testCase "Should fail on sequence when no sequence is specified"+          $ let unscrambler =+                  U.value [] (Just mapping) Nothing+                  where+                    mapping =+                      U.foldMapping (,) Fold.list U.textString value+                      where+                        value =+                          U.value [nullScalar, intScalar] Nothing Nothing+                          where+                            nullScalar =+                              U.nullScalar Nothing+                            intScalar =+                              fmap Just $ U.boundedIntegerScalar @Int (U.Signed True) U.DecimalNumeralSystem+                input =+                  [NeatInterpolation.text|                   a: 2                   b: 3                   c:                     - 1                     - 2                 |]-           in case U.parseText unscrambler input of-                Right res ->-                  assertFailure (show res)-                Left failure ->-                  assertEqual (Text.unpack failure) "Error at path /c. Unexpected sequence value" failure,-        testCase "Domain sum-type regression" $-          let unscrambler =-                doc-                where-                  doc =-                    U.mappingValue $-                      U.byKeyMapping (U.CaseSensitive True) $-                        asum+             in case U.parseText unscrambler input of+                  Right res ->+                    assertFailure (show res)+                  Left failure ->+                    assertEqual (Text.unpack failure) "Error at path /c. Unexpected sequence value" failure,+        testCase "Domain sum-type regression"+          $ let unscrambler =+                  doc+                  where+                    doc =+                      U.mappingValue+                        $ U.byKeyMapping (U.CaseSensitive True)+                        $ asum                           [ Just <$> U.atByKey "sums" sum,                             pure Nothing                           ]-                  sum =-                    U.mappingValue $-                      U.foldMapping (,) Fold.list U.textString sumVariant-                  sumVariant =-                    U.mappingValue $-                      U.foldMapping (,) Fold.list U.textString params-                  params =-                    U.value [nullScalar, intScalar] Nothing Nothing-                    where-                      nullScalar =-                        U.nullScalar Nothing-                      intScalar =-                        fmap Just $ U.boundedIntegerScalar @Int (U.Signed True) U.DecimalNumeralSystem-              input =-                [NeatInterpolation.text|+                    sum =+                      U.mappingValue+                        $ U.foldMapping (,) Fold.list U.textString sumVariant+                    sumVariant =+                      U.mappingValue+                        $ U.foldMapping (,) Fold.list U.textString params+                    params =+                      U.value [nullScalar, intScalar] Nothing Nothing+                      where+                        nullScalar =+                          U.nullScalar Nothing+                        intScalar =+                          fmap Just $ U.boundedIntegerScalar @Int (U.Signed True) U.DecimalNumeralSystem+                input =+                  [NeatInterpolation.text|                   sums:                     A:                       a:@@ -74,81 +74,81 @@                         - Bool                       b: Char, Double                 |]-           in case U.parseText unscrambler input of-                Right res ->-                  assertFailure (show res)-                Left failure ->-                  assertEqual "" "Error at path /sums/A/a. Unexpected sequence value" failure,-        testCase "Domain sum-type correct" $-          let unscrambler =-                doc-                where-                  doc =-                    U.mappingValue $-                      U.byKeyMapping (U.CaseSensitive True) $-                        asum+             in case U.parseText unscrambler input of+                  Right res ->+                    assertFailure (show res)+                  Left failure ->+                    assertEqual "" "Error at path /sums/A/a. Unexpected sequence value" failure,+        testCase "Domain sum-type correct"+          $ let unscrambler =+                  doc+                  where+                    doc =+                      U.mappingValue+                        $ U.byKeyMapping (U.CaseSensitive True)+                        $ asum                           [ Just <$> U.atByKey "sums" sum,                             pure Nothing                           ]-                  sum =-                    U.mappingValue $-                      U.foldMapping (,) Fold.list U.textString sumVariant-                  sumVariant =-                    U.mappingValue $-                      U.foldMapping (,) Fold.list U.textString params-                  params =-                    U.value [nullScalar, valueScalar] Nothing Nothing-                    where-                      nullScalar =-                        U.nullScalar Nothing-                      valueScalar =-                        fmap Just $ U.stringScalar U.textString-              input =-                [NeatInterpolation.text|+                    sum =+                      U.mappingValue+                        $ U.foldMapping (,) Fold.list U.textString sumVariant+                    sumVariant =+                      U.mappingValue+                        $ U.foldMapping (,) Fold.list U.textString params+                    params =+                      U.value [nullScalar, valueScalar] Nothing Nothing+                      where+                        nullScalar =+                          U.nullScalar Nothing+                        valueScalar =+                          fmap Just $ U.stringScalar U.textString+                input =+                  [NeatInterpolation.text|                   sums:                     A:                       a: Text                       b: Int                 |]-           in case U.parseText unscrambler input of-                Right res ->-                  assertEqual "" (Just [("A", [("a", Just "Text"), ("b", Just "Int")])]) res-                Left failure ->-                  assertFailure (Text.unpack failure),-        testCase "Scalar errors are readable" $-          let unscrambler =-                doc-                where-                  doc =-                    U.mappingValue $-                      U.byKeyMapping (U.CaseSensitive True) $-                        asum+             in case U.parseText unscrambler input of+                  Right res ->+                    assertEqual "" (Just [("A", [("a", Just "Text"), ("b", Just "Int")])]) res+                  Left failure ->+                    assertFailure (Text.unpack failure),+        testCase "Scalar errors are readable"+          $ let unscrambler =+                  doc+                  where+                    doc =+                      U.mappingValue+                        $ U.byKeyMapping (U.CaseSensitive True)+                        $ asum                           [ Just <$> U.atByKey "sums" sum,                             pure Nothing                           ]-                  sum =-                    U.mappingValue $-                      U.foldMapping (,) Fold.list U.textString sumVariant-                  sumVariant =-                    U.mappingValue $-                      U.foldMapping (,) Fold.list U.textString params-                  params =-                    U.value [nullScalar, intScalar] Nothing Nothing-                    where-                      nullScalar =-                        U.nullScalar Nothing-                      intScalar =-                        fmap Just $ U.boundedIntegerScalar @Int (U.Signed True) U.DecimalNumeralSystem-              input =-                [NeatInterpolation.text|+                    sum =+                      U.mappingValue+                        $ U.foldMapping (,) Fold.list U.textString sumVariant+                    sumVariant =+                      U.mappingValue+                        $ U.foldMapping (,) Fold.list U.textString params+                    params =+                      U.value [nullScalar, intScalar] Nothing Nothing+                      where+                        nullScalar =+                          U.nullScalar Nothing+                        intScalar =+                          fmap Just $ U.boundedIntegerScalar @Int (U.Signed True) U.DecimalNumeralSystem+                input =+                  [NeatInterpolation.text|                   sums:                     A:                       a: Int                       b: Char                 |]-           in case U.parseText unscrambler input of-                Right res ->-                  assertFailure (show res)-                Left failure ->-                  assertEqual "" "Error at path /sums/A/a. Expecting one of the following formats: null, signed decimal. Got input: \"Int\"" failure+             in case U.parseText unscrambler input of+                  Right res ->+                    assertFailure (show res)+                  Left failure ->+                    assertEqual "" "Error at path /sums/A/a. Expecting one of the following formats: null, signed decimal. Got input: \"Int\"" failure       ]
yaml-unscrambler.cabal view
@@ -1,7 +1,11 @@ cabal-version: 3.0 name:          yaml-unscrambler-version:       0.1.0.17+version:       0.1.0.18 synopsis:      Flexible declarative YAML parsing toolkit+description:+  Very flexible declarative YAML parsing toolkit with extensive error detalization capabilities and expected schema generation.++category:      Parsers, Parser, YAML homepage:      https://github.com/nikita-volkov/yaml-unscrambler bug-reports:   https://github.com/nikita-volkov/yaml-unscrambler/issues author:        Nikita Volkov <nikita.y.volkov@mail.ru>@@ -86,9 +90,9 @@     , attoparsec-time >=1.0.1.2 && <1.1     , base >=4.13 && <5     , base64-bytestring >=1.2.1 && <1.3-    , bytestring >=0.10 && <0.12+    , bytestring >=0.10 && <0.13     , conduit >=1.3.2 && <1.4-    , containers >=0.6.2 && <0.7+    , containers >=0.6.2 && <0.8     , foldl >=1.4 && <2     , hashable >=1.4 && <2     , libyaml >=0.1.2 && <0.2