packages feed

kit-0.5.2: Kit/Model.hs

module Kit.Model where

  import Text.JSON
  import Control.Applicative
  import System.FilePath.Posix

  data KitSpec = KitSpec {
    specKit :: Kit,
    specDependencies :: [Kit],
    specSourceDirectory :: FilePath,
    specTestDirectory :: FilePath,
    specLibDirectory :: FilePath,
    specPrefixFile :: FilePath,
    specConfigFile :: FilePath,
    specKitDepsXcodeFlags :: Maybe String
  } deriving (Show, Read)

  type Version = String

  data Kit = Kit {
    kitName :: String,
    kitVersion :: Version
  } deriving (Eq, Show, Ord, Read)

  kitFileName :: Kit -> String
  kitFileName k = kitName k ++ "-" ++ kitVersion k

  defaultSpecForKit :: Kit -> KitSpec
  defaultSpecForKit kit = KitSpec kit [] "src" "test" "lib" "Prefix.pch" "Config.xcconfig" Nothing
  -- TODO make this and the json reading use the same defaults
  -- I suspect that to do this I'll need update functions for each of
  -- fields in the KitSpec record.
  -- Look at the 'lenses' package on haskell.

  instance JSON Kit where
      showJSON kit = makeObj [ ("name", w kitName) , ("version", w kitVersion) ] where w f = showJSON . f $ kit

      readJSON (JSObject obj) = Kit <$> f "name" <*> f "version"
                                  where f x = f' obj x 

  instance JSON KitSpec where
      showJSON spec = makeObj [
            ("name", showJSON $ kitName kit)
          , ("version", showJSON $ kitVersion kit)
          , ("dependencies", showJSON $ specDependencies spec)
          ]
          where kit = specKit spec

      readJSON js@(JSObject obj) =
              KitSpec <$> readJSON js 
                      <*> (f "dependencies" <|> pure []) 
                      <*> (f "source-directory" <|> pure "src")
                      <*> (f "test-directory" <|> pure "test")
                      <*> (f "lib-directory" <|> pure "lib")
                      <*> (f "prefix-header" <|> pure "Prefix.pch")
                      <*> (f "xcconfig" <|> pure "Config.xcconfig")
                      <*> (Just <$> f "kitdeps-xcode-flags" <|> pure Nothing)
        where f x = f' obj x

  f' obj x = mLookup x (fromJSObject obj) >>= readJSON

  mLookup :: Monad m => String -> [(String, b)] -> m b
  mLookup a as = maybe (fail $ "No such element: " ++ a) return (lookup a as)