packages feed

simpleconfig 0.0.9 → 0.0.10

raw patch · 3 files changed

+119/−30 lines, 3 filesdep +eitherdep +hspecPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: either, hspec

API changes (from Hackage documentation)

- Config.Simple: instance Config.Simple.GFromPartialConfig fp fc => Config.Simple.GFromPartialConfig (GHC.Generics.M1 i m fp) (GHC.Generics.M1 i m fc)
- Config.Simple: instance Config.Simple.GFromPartialConfigMember partial complete => Config.Simple.GFromPartialConfig (GHC.Generics.Rec0 partial) (GHC.Generics.Rec0 complete)
+ Config.Simple: AccumFor :: (a -> s -> s) -> AccumFor s a
+ Config.Simple: configLensPartial :: forall config. (Generic (config CPartial), Generic (LensConfig CPartial config), GLensFor (config CPartial) (Rep (config CPartial)) (Rep (LensConfig CPartial config))) => LensConfig CPartial config
+ Config.Simple: instance (Config.Simple.GFromPartialConfigMaybe fp fc, GHC.Generics.Selector m) => Config.Simple.GFromPartialConfig (GHC.Generics.S1 m fp) (GHC.Generics.S1 m fc)
+ Config.Simple: instance Config.Simple.GFromPartialConfig fp fc => Config.Simple.GFromPartialConfig (GHC.Generics.C1 m fp) (GHC.Generics.C1 m fc)
+ Config.Simple: instance Config.Simple.GFromPartialConfig fp fc => Config.Simple.GFromPartialConfig (GHC.Generics.D1 m fp) (GHC.Generics.D1 m fc)
+ Config.Simple: instance Config.Simple.GFromPartialConfigMember partial complete => Config.Simple.GFromPartialConfigMaybe (GHC.Generics.Rec0 partial) (GHC.Generics.Rec0 complete)
+ Config.Simple: instance Config.Simple.GLensFor root (GHC.Generics.Rec0 (Data.Monoid.Last x)) (GHC.Generics.Rec0 (Config.Simple.AccumFor root x))
+ Config.Simple: instance Config.Simple.GLensFor root (GHC.Generics.Rec0 Data.Monoid.Any) (GHC.Generics.Rec0 (Config.Simple.AccumFor root GHC.Types.Bool))
+ Config.Simple: instance GHC.Classes.Ord a => Config.Simple.GLensFor root (GHC.Generics.Rec0 (Data.Set.Internal.Set a)) (GHC.Generics.Rec0 (Config.Simple.AccumFor root a))
+ Config.Simple: newtype AccumFor s a
- Config.Simple: configLens :: forall config k. (Generic (config k), Generic (LensConfig k config), GLensFor (config k) (Rep (config k)) (Rep (LensConfig k config))) => LensConfig k config
+ Config.Simple: configLens :: forall config. (Generic (config CComplete), Generic (LensConfig CComplete config), GLensFor (config CComplete) (Rep (config CComplete)) (Rep (LensConfig CComplete config))) => LensConfig CComplete config
- Config.Simple: fromPartialConfig :: (Generic (Partial config), Generic (Complete config), GFromPartialConfig (Rep (Partial config)) (Rep (Complete config))) => Partial config -> Maybe (Complete config)
+ Config.Simple: fromPartialConfig :: (Generic (Partial config), Generic (Complete config), GFromPartialConfig (Rep (Partial config)) (Rep (Complete config)), IsString text) => Partial config -> Validation [text] (Complete config)

Files

simpleconfig.cabal view
@@ -1,11 +1,11 @@--- This file has been generated from package.yaml by hpack version 0.20.0.+-- This file has been generated from package.yaml by hpack version 0.28.2. -- -- see: https://github.com/sol/hpack ----- hash: 1f3e3450009bfd77e7430ed520edd3aa0c946c5dd117d5f40be0ee518511d9b5+-- hash: 3985e307c00f6905bfb6d5a656f0c09031bd4c0a8d158c15cb73db132796ebaa  name:           simpleconfig-version:        0.0.9+version:        0.0.10 synopsis:       Short description of your package description:    Please see the README on Github at <https://github.com/koterpillar/simpleconfig#readme> category:       Web@@ -18,7 +18,6 @@ license-file:   LICENSE build-type:     Simple cabal-version:  >= 1.10- extra-source-files:     README.md @@ -27,31 +26,34 @@   location: https://github.com/koterpillar/simpleconfig  library+  exposed-modules:+      Config.Simple+  other-modules:+      Paths_simpleconfig   hs-source-dirs:       src   build-depends:       base >=4.7 && <5     , containers+    , either     , lens-  exposed-modules:-      Config.Simple-  other-modules:-      Paths_simpleconfig   default-language: Haskell2010  test-suite simpleconfig-test   type: exitcode-stdio-1.0   main-is: Spec.hs+  other-modules:+      Paths_simpleconfig   hs-source-dirs:       test   ghc-options: -threaded -rtsopts -with-rtsopts=-N   build-depends:       base     , containers+    , either     , generic-deriving+    , hspec     , lens     , simpleconfig     , text-  other-modules:-      Paths_simpleconfig   default-language: Haskell2010
src/Config/Simple.hs view
@@ -12,6 +12,7 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE UndecidableInstances #-}  module Config.Simple   ( ConfigBool@@ -20,14 +21,19 @@   , Partial   , Complete   , LensFor(..)+  , AccumFor(..)   , configLens+  , configLensPartial   , fromPartialConfig   ) where  import Control.Lens +import Data.Either.Validation import Data.Monoid (Any(..), Last(..)) import Data.Set (Set)+import qualified Data.Set as Set+import Data.String (IsString(..))  import GHC.Generics import qualified GHC.Generics as G@@ -39,25 +45,41 @@  data CComplete +data CAccum+ data CLensFor k c +type family ConfigLensTarget k where+  ConfigLensTarget CComplete = CComplete+  ConfigLensTarget CPartial = CAccum++type family ConfigLensFor k s a where+  ConfigLensFor CComplete s a = LensFor s a+  ConfigLensFor CPartial s a = AccumFor s a+ newtype LensFor s a =   LensFor (Lens' s a) +newtype AccumFor s a =+  AccumFor (a -> s -> s)+ type family ConfigLast a k where   ConfigLast a CPartial = Last a   ConfigLast a CComplete = a-  ConfigLast a (CLensFor k root) = LensFor root (ConfigLast a k)+  ConfigLast a CAccum = a+  ConfigLast a (CLensFor k root) = ConfigLensFor k root (ConfigLast a (ConfigLensTarget k))  type family ConfigBool k where   ConfigBool CPartial = Any   ConfigBool CComplete = Bool-  ConfigBool (CLensFor k root) = LensFor root (ConfigBool k)+  ConfigBool CAccum = Bool+  ConfigBool (CLensFor k root) = ConfigLensFor k root (ConfigBool (ConfigLensTarget k))  type family ConfigSet a k where   ConfigSet a CPartial = Set a   ConfigSet a CComplete = Set a-  ConfigSet a (CLensFor k root) = LensFor root (ConfigSet a k)+  ConfigSet a CAccum = a+  ConfigSet a (CLensFor k root) = ConfigLensFor k root (ConfigSet a (ConfigLensTarget k))  type Partial config = config CPartial @@ -69,29 +91,45 @@      ( Generic (Partial config)      , Generic (Complete config)      , GFromPartialConfig (Rep (Partial config)) (Rep (Complete config))+     , IsString text      )   => Partial config-  -> Maybe (Complete config)+  -> Validation [text] (Complete config) fromPartialConfig = fmap G.to . gFromPartialConfig . G.from  class GFromPartialConfig (repPartial :: * -> *) (repComplete :: * -> *) where-  gFromPartialConfig :: repPartial x -> Maybe (repComplete x)+  gFromPartialConfig :: IsString text => repPartial x -> Validation [text] (repComplete x)  instance GFromPartialConfig fp fc =>-         GFromPartialConfig (M1 i m fp) (M1 i m fc) where+         GFromPartialConfig (D1 m fp) (D1 m fc) where   gFromPartialConfig (M1 x) = M1 <$> gFromPartialConfig x +instance GFromPartialConfig fp fc =>+         GFromPartialConfig (C1 m fp) (C1 m fc) where+  gFromPartialConfig (M1 x) = M1 <$> gFromPartialConfig x+ instance (GFromPartialConfig ap ac, GFromPartialConfig bp bc) =>          GFromPartialConfig (ap :*: bp) (ac :*: bc) where   gFromPartialConfig (a :*: b) =     liftA2 (:*:) (gFromPartialConfig a) (gFromPartialConfig b) +instance (GFromPartialConfigMaybe fp fc, Selector m) =>+         GFromPartialConfig (S1 m fp) (S1 m fc) where+  gFromPartialConfig v@(M1 x) =+    fmap M1 $+    case gFromPartialConfigMaybe x of+      Just r -> Success r+      Nothing -> Failure [fromString $ selName v]++class GFromPartialConfigMaybe (repPartial :: * -> *) (repComplete :: * -> *) where+  gFromPartialConfigMaybe :: repPartial x -> Maybe (repComplete x)+ class GFromPartialConfigMember partial complete where   gFromPartialConfigMember :: partial -> Maybe complete  instance GFromPartialConfigMember partial complete =>-         GFromPartialConfig (Rec0 partial) (Rec0 complete) where-  gFromPartialConfig (K1 a) = K1 <$> gFromPartialConfigMember a+         GFromPartialConfigMaybe (Rec0 partial) (Rec0 complete) where+  gFromPartialConfigMaybe (K1 a) = K1 <$> gFromPartialConfigMember a  instance GFromPartialConfigMember Any Bool where   gFromPartialConfigMember = Just . getAny@@ -102,20 +140,38 @@ instance GFromPartialConfigMember (Last a) a where   gFromPartialConfigMember = getLast -configLens ::+configLens' ::      forall config k.      ( Generic (config k)      , Generic (LensConfig k config)      , GLensFor (config k) (Rep (config k)) (Rep (LensConfig k config))      )   => LensConfig k config-configLens = G.to $ gToLensFor rootLens+configLens' = G.to $ gToLensFor rootLens   where     rootLens ::          forall x. Generic (config k)       => Lens' (config k) (Rep (config k) x)     rootLens = G.generic +configLens ::+     forall config.+     ( Generic (config CComplete)+     , Generic (LensConfig CComplete config)+     , GLensFor (config CComplete) (Rep (config CComplete)) (Rep (LensConfig CComplete config))+     )+  => LensConfig CComplete config+configLens = configLens'++configLensPartial ::+     forall config.+     ( Generic (config CPartial)+     , Generic (LensConfig CPartial config)+     , GLensFor (config CPartial) (Rep (config CPartial)) (Rep (LensConfig CPartial config))+     )+  => LensConfig CPartial config+configLensPartial = configLens'+ class GLensFor root rep repLens where   gToLensFor :: Lens' root (rep x) -> repLens x @@ -129,3 +185,12 @@  instance GLensFor root (Rec0 x) (Rec0 (LensFor root x)) where   gToLensFor rootLens = K1 $ LensFor $ rootLens . G._K1++instance GLensFor root (Rec0 (Last x)) (Rec0 (AccumFor root x)) where+  gToLensFor rootLens = K1 $ AccumFor $ \v s -> s & rootLens . G._K1 <>~ Last (Just v)++instance GLensFor root (Rec0 Any) (Rec0 (AccumFor root Bool)) where+  gToLensFor rootLens = K1 $ AccumFor $ \v s -> s & rootLens . G._K1 <>~ Any v++instance Ord a => GLensFor root (Rec0 (Set a)) (Rec0 (AccumFor root a)) where+  gToLensFor rootLens = K1 $ AccumFor $ \v s -> s & rootLens . G._K1 <>~ Set.singleton v
test/Spec.hs view
@@ -11,7 +11,9 @@ import Control.Lens import Control.Monad +import Data.Either.Validation import Data.Foldable+import Data.Maybe import Data.Monoid (Last(..)) import Data.Set (Set) import qualified Data.Set as Set@@ -23,6 +25,8 @@  import GHC.Generics +import Test.Hspec+ import Config.Simple  data ConfigF k = Config@@ -49,14 +53,32 @@  Config (LensFor address) (LensFor dryRun) (LensFor widgets) = configLens +Config (AccumFor address') (AccumFor dryRun') (AccumFor widgets') =+  configLensPartial++isSuccess :: Validation e a -> Bool+isSuccess (Success _) = True+isSuccess (Failure _) = False+ main :: IO ()-main = do-  let config' =-        mempty & (address <>~ pure "Silverpond") & (dryRun <>~ Any True) &-        (widgets <>~ Set.singleton "blah") &-        (address <>~ pure "SEEK")-  print config'-  let (Just config) = fromPartialConfig config'-  Text.putStrLn $ "Address = " <> config ^. address-  when (config ^. dryRun) $ Text.putStrLn "Dry run"-  for_ (config ^. widgets) $ \widget -> Text.putStrLn $ "Widget = " <> widget+main =+  hspec $+  describe "fromPartialConfig" $ do+    context "with a complete config" $ do+      let config' =+            mempty & address' "Silverpond" & dryRun' True & widgets' "blah" &+            address' "SEEK"+      let result = fromPartialConfig config'+      it "should succeed" $ result `shouldSatisfy` isSuccess+      let (Success config) = fromPartialConfig config'+      it "should override Last members with later assignments" $+        config ^. address `shouldBe` "SEEK"+      it "should turn on Any members" $ config ^. dryRun `shouldBe` True+      it "should record set members" $+        config ^. widgets `shouldBe` Set.fromList ["blah"]+    context "with incomplete config" $ do+      let config' = mempty & dryRun' True+      let result = fromPartialConfig config'+      it "should return a failure" $ result `shouldNotSatisfy` isSuccess+      let (Failure fields) = fromPartialConfig config'+      it "should return missing fields" $ fields `shouldBe` ["_address"]