path 0.5.7 → 0.5.8
raw patch · 5 files changed
+62/−7 lines, 5 filesdep +aeson
Dependencies added: aeson
Files
- CHANGELOG +3/−0
- path.cabal +3/−1
- src/Path.hs +28/−0
- src/Path/Internal.hs +10/−0
- test/Main.hs +18/−6
CHANGELOG view
@@ -1,3 +1,6 @@+0.5.8+ * Add Aeson instances.+ 0.5.7: * Fix haddock problem. 0.5.6:
path.cabal view
@@ -1,5 +1,5 @@ name: path-version: 0.5.7+version: 0.5.8 synopsis: Support for well-typed paths description: Support for will-typed paths. license: BSD3@@ -21,12 +21,14 @@ , filepath , template-haskell , deepseq+ , aeson test-suite test type: exitcode-stdio-1.0 main-is: Main.hs hs-source-dirs: test build-depends: HUnit+ , aeson , base , hspec , mtl
src/Path.hs view
@@ -12,6 +12,7 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE FlexibleInstances #-} module Path (-- * Types@@ -49,6 +50,8 @@ import Control.Exception (Exception) import Control.Monad.Catch (MonadThrow(..))+import Data.Aeson (FromJSON (..))+import qualified Data.Aeson.Types as Aeson import Data.Data import Data.List import Data.Maybe@@ -70,6 +73,31 @@ -- | A directory path. data Dir deriving (Typeable)++instance FromJSON (Path Abs File) where+ parseJSON = parseJSONWith parseAbsFile+ {-# INLINE parseJSON #-}++instance FromJSON (Path Rel File) where+ parseJSON = parseJSONWith parseRelFile+ {-# INLINE parseJSON #-}++instance FromJSON (Path Abs Dir) where+ parseJSON = parseJSONWith parseAbsDir+ {-# INLINE parseJSON #-}++instance FromJSON (Path Rel Dir) where+ parseJSON = parseJSONWith parseRelDir+ {-# INLINE parseJSON #-}++parseJSONWith :: (Show e, FromJSON a)+ => (a -> Either e b) -> Aeson.Value -> Aeson.Parser b+parseJSONWith f x =+ do fp <- parseJSON x+ case f fp of+ Right p -> return p+ Left e -> fail (show e)+{-# INLINE parseJSONWith #-} -- | Exception when parsing a location. data PathParseException
src/Path/Internal.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} -- | Internal types and functions.@@ -7,6 +8,7 @@ where import Control.DeepSeq (NFData (..))+import Data.Aeson (ToJSON (..)) import Data.Data -- | Path of some base and type.@@ -47,3 +49,11 @@ instance NFData (Path b t) where rnf (Path x) = rnf x++instance ToJSON (Path b t) where+ toJSON (Path x) = toJSON x+ {-# INLINE toJSON #-}+#if MIN_VERSION_aeson(0,10,0)+ toEncoding (Path x) = toEncoding x+ {-# INLINE toEncoding #-}+#endif
test/Main.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE OverloadedStrings #-} -- | Test suite. @@ -6,8 +7,8 @@ import Control.Applicative import Control.Monad+import Data.Aeson import Data.Maybe-import Data.Monoid import Path import Path.Internal import Test.Hspec@@ -29,6 +30,7 @@ describe "Operations: parent" operationParent describe "Operations: filename" operationFilename describe "Restrictions" restrictions+ describe "Aeson Instances" aesonInstances -- | Restricting the input of any tricks. restrictions :: Spec@@ -214,12 +216,22 @@ parserTest parser input expected = it ((case expected of Nothing -> "Failing: "- Just{} -> "Succeeding: ") <>- "Parsing " <>- show input <>- " " <>+ Just{} -> "Succeeding: ") +++ "Parsing " +++ show input +++ " " ++ case expected of Nothing -> "should fail."- Just x -> "should succeed with: " <> show x)+ Just x -> "should succeed with: " ++ show x) (actual == expected) where actual = parser input++-- | Tests for the 'ToJSON' and 'FromJSON' instances+aesonInstances :: Spec+aesonInstances =+ do it "Decoding \"[\"/foo/bar\"]\" as a [Path Abs Dir] should succeed." $+ eitherDecode "[\"/foo/bar\"]" `shouldBe` Right [Path "/foo/bar/" :: Path Abs Dir]+ it "Decoding \"[\"/foo/bar\"]\" as a [Path Rel Dir] should fail." $+ decode "[\"/foo/bar\"]" `shouldBe` (Nothing :: Maybe [Path Rel Dir])+ it "Encoding \"[\"/foo/bar/mu.txt\"]\" should succeed." $+ encode [Path "/foo/bar/mu.txt" :: Path Abs File] `shouldBe` "[\"/foo/bar/mu.txt\"]"