ValveValueKeyvalue 1.0.1.0 → 1.1.0.0
raw patch · 5 files changed
+53/−36 lines, 5 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
- Text.ValveVKV: (.:) :: ValveVKV a => ValveKeyValueEntry -> String -> Maybe a
+ Text.ValveVKV: (.:) :: ValveVKV a => ValveKeyValueEntry -> String -> Either String a
- Text.ValveVKV: fromValveVKV :: ValveVKV a => ValveKeyValueEntry -> Context -> Maybe a
+ Text.ValveVKV: fromValveVKV :: ValveVKV a => ValveKeyValueEntry -> Context -> Either String a
- Text.ValveVKV: parseValveVKV :: ValveVKV a => String -> Maybe a
+ Text.ValveVKV: parseValveVKV :: ValveVKV a => String -> Either String a
Files
- CHANGELOG.md +14/−1
- README.md +4/−2
- ValveValueKeyvalue.cabal +6/−3
- app/Text/ValveVKV.hs +6/−4
- app/Text/ValveVKV/Class.hs +23/−26
CHANGELOG.md view
@@ -1,5 +1,18 @@ # Revision history for ValveValueKeyvalue -## 0.1.0.0 -- YYYY-mm-dd +## 1.0.0.0 -- 2021-09-27 * First version. Released on an unsuspecting world. + +## 1.0.1.0 -- 2021-09-28 + +* Added parseToVKV function and added some documentation + +## 1.1.0.0 -- yyyy-mm-dd + +* Changed class to use Either +* Updated documentation +* Changed export order so haddock makes better documentation +* Added tested-with in cabal file +* Changed list instance of ValveVKV to always return Right. In case no items are found, return Right []. To get a list that is certain to not be empty, use NonEmpty from the Data.List.NonEmpty module in base +* Fixed example in readme
README.md view
@@ -13,9 +13,11 @@ So you can now run ``` -a :: IO My +a :: IO (Either String My) a = do contents <- readFile "file.txt" return $ parseValveVKV contents ``` -This will open file "file.txt", read its contents and return the "My" type.+This will open file "file.txt", read its contents and return the "My" type. + +Avaliable on [Hackage](https://hackage.haskell.org/package/ValveValueKeyvalue)
ValveValueKeyvalue.cabal view
@@ -1,12 +1,14 @@ cabal-version: 2.4 name: ValveValueKeyvalue -version: 1.0.1.0 +version: 1.1.0.0 -- A short (one-line) description of the package. synopsis: A Valve Value-keyvalue parser for Haskell made with Parsec. -- A longer description of the package. -description: This is a package made to parse Valve's value-keyvalue format, common in Source Engine games. Valve value-keyvalue files may take the extensions ".pop" or ".vtf". The main module is Text.ValveVKV. The main function you will be using is parseValveVKV. +description: This is a package made to parse Valve's value-keyvalue format, common in Source Engine games. + Valve value-keyvalue files may take the extensions ".pop" or ".vtf". The main module is Text.ValveVKV. + The main function you will be using is parseValveVKV. -- A URL where users can report bugs. homepage: https://github.com/BernardoGomesNegri/ValveValueKeyvalue @@ -20,6 +22,7 @@ category: Parsing extra-source-files: CHANGELOG.md, README.md +tested-with: GHC ==8.10.5 || ==8.10.7 source-repository head type: git @@ -34,7 +37,7 @@ -- LANGUAGE extensions used by modules in this package. -- other-extensions: - build-depends: base ^>= 4.14.2.0 + build-depends: base >= 4.14.2.0 && < 4.16 build-depends: parsec >= 3.1.14 && < 3.2 hs-source-dirs: app default-language: Haskell2010
app/Text/ValveVKV.hs view
@@ -1,5 +1,5 @@-module Text.ValveVKV(vkvParser, parseValveVKV, fromValveVKV, (.:), (^:), unpair, ValveVKV, - ValveKeyValueEntry(KVObject, KVInt, KVString), Pair (Pair), Context, parseToVKV) where +module Text.ValveVKV(parseValveVKV, parseToVKV, fromValveVKV, (.:), (^:), ValveVKV, + ValveKeyValueEntry(KVObject, KVInt, KVString), Pair (Pair), unpair, Context, vkvParser) where -- Library for processing Valve's value keyvalue format. The main function you will wish to use is parseValveVKV. To convert it into your own type, you -- will need to write a 'ValveVKV' instance for it. @@ -9,15 +9,17 @@ import Data.Maybe (mapMaybe) -- | The main function you will be using. Turns the ValveVKV string into a type that has the 'ValveVKV' typeclass. -parseValveVKV :: ValveVKV a => String -> Maybe a +parseValveVKV :: ValveVKV a => String -> Either String a parseValveVKV input = let parseRes = parse vkvParser "" input in case parseRes of - Left _ -> Nothing + Left s -> Left (show s) Right a -> let topObj = KVObject (Pair "top" a) in fromValveVKV topObj topObj -- | Parses it directly to a list of entries. Most of the times, 'parseValveVKV' will be better to directly turn it into a Haskell type of your choice +-- +-- @since 1.0.1.0 parseToVKV :: String -> Either ParseError [ValveKeyValueEntry] parseToVKV = parse vkvParser ""
app/Text/ValveVKV/Class.hs view
@@ -16,16 +16,16 @@ finder this@(KVInt (Pair thisname s)) = if thisname == name then Just this else Nothing findFromName _ _ = [] --- | This operator receives an entry on the left side and a string on the right side. It tries to find the string subentry named the string inside the entry you gave in on the left. -(.:) :: ValveVKV a => ValveKeyValueEntry -> String -> Maybe a +-- | This operator receives an entry on the left side and a string on the right side. It tries to find the subentry named the string inside the entry you gave in on the left. +(.:) :: ValveVKV a => ValveKeyValueEntry -> String -> Either String a context .: name = let results = findFromName context name in case results of - [] -> Nothing + [] -> Left $ "No items with name " ++ " " ++ name x:_ -> fromValveVKV x context infixl 5 .: --- | This operator receives an entry on the left side and a string on the right side. It tries to find the subentry named the string inside the entry you gave in on the left. +-- | This operator receives an entry on the left side and a string on the right side. It tries to find the string subentry named the string inside the entry you gave in on the left. (^:) :: ValveKeyValueEntry -> String -> Maybe String context ^: name = let results = findFromName context name in @@ -51,41 +51,38 @@ -- @ class ValveVKV a where -- | The first argument is the entry that should be turned into the type. The second argument is the entry just above that. - fromValveVKV :: ValveKeyValueEntry -> Context -> Maybe a + fromValveVKV :: ValveKeyValueEntry -> Context -> Either String a instance ValveVKV Int where - fromValveVKV (KVInt (Pair _ num)) _ = Just num - fromValveVKV _ _ = Nothing + fromValveVKV (KVInt (Pair _ num)) _ = Right num + fromValveVKV (KVString (Pair name x)) _ = Left $ "No int called " ++ name ++ " found. We did find a string with value " ++ x + fromValveVKV (KVObject (Pair name _)) _ = Left $ "No int called " ++ name ++ " found. We did find an object named " ++ name instance ValveVKV a => ValveVKV (Maybe a) where - fromValveVKV entry con = Just (fromValveVKV entry con) + fromValveVKV entry con = fromValveVKV entry con instance ValveVKV Bool where - fromValveVKV (KVInt (Pair _ 0)) _ = Just False - fromValveVKV (KVInt (Pair _ 1)) _ = Just True - fromValveVKV _ _ = Nothing + fromValveVKV (KVInt (Pair _ 0)) _ = Right False + fromValveVKV (KVInt (Pair _ 1)) _ = Right True + fromValveVKV (KVInt (Pair _ x)) _ = Left $ "Could not parse int " ++ show x ++ " as a boolean" + fromValveVKV _ _ = Left "Could not parse as a boolean" instance ValveVKV a => ValveVKV [a] where fromValveVKV (KVString (Pair name _)) context = - let results = mapMaybe (`fromValveVKV` context) (findFromName context name) in - case results of - [] -> Nothing - _ -> Just results + --Right $ map (`fromValveVKV` context) (findFromName context name) + traverse (`fromValveVKV` context) (findFromName context name) fromValveVKV (KVObject (Pair name _)) context = - let results = mapMaybe (`fromValveVKV` context) (findFromName context name) in - case results of - [] -> Nothing - _ -> Just results + traverse (`fromValveVKV` context) (findFromName context name) fromValveVKV (KVInt (Pair name _)) context = - let results = mapMaybe (`fromValveVKV` context) (findFromName context name) in - case results of - [] -> Nothing - _ -> Just results + traverse (`fromValveVKV` context) (findFromName context name) instance ValveVKV a => ValveVKV (NonEmpty a) where fromValveVKV entry context = - list >>= nonEmpty + --list >>= nonEmpty + list >>= \xs -> + case nonEmpty xs of + Just x -> Right x + Nothing -> Left "List was empty" where - list :: ValveVKV a => Maybe [a] + list :: ValveVKV a => Either String [a] list = fromValveVKV entry context -