1{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DeriveFoldable #-}
3{-# LANGUAGE DeriveFunctor #-}
4{-# LANGUAGE DeriveGeneric #-}
5{-# LANGUAGE DeriveTraversable #-}
6{-# LANGUAGE ExtendedDefaultRules #-}
7{-# LANGUAGE FlexibleContexts #-}
8{-# LANGUAGE FlexibleInstances #-}
9{-# LANGUAGE FunctionalDependencies #-}
10{-# LANGUAGE GeneralizedNewtypeDeriving #-}
11{-# LANGUAGE KindSignatures #-}
12{-# LANGUAGE LambdaCase #-}
13{-# LANGUAGE MultiParamTypeClasses #-}
14{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE RankNTypes #-}
16{-# LANGUAGE RecordWildCards #-}
17{-# LANGUAGE TemplateHaskell #-}
18{-# LANGUAGE ViewPatterns #-}
20{-# OPTIONS_GHC -fno-warn-type-defaults #-}
23-- Copyright : (c) 2015-2016 Brendan Hay
24-- License : Mozilla Public License, v. 2.0.
25-- Maintainer : Brendan Hay <brendan.g.hay@gmail.com>
26-- Stability : provisional
27-- Portability : non-portable (GHC extensions)
31 , module Gen.Types.Help
33 , module Gen.Types.Map
35 , module Gen.Types.Schema
36 , module Gen.Types.Data
39import Control.Applicative
40import Control.Lens hiding ((.=))
41import Control.Monad.Except
42import Control.Monad.State.Strict
43import Data.Aeson hiding (Array, Bool, String)
44import qualified Data.Attoparsec.Text as A
46import Data.CaseInsensitive (CI)
47import qualified Data.CaseInsensitive as CI
48import Data.Function (on)
49import qualified Data.HashMap.Strict as Map
50import qualified Data.HashSet as Set
51import Data.List (sort)
54import Data.Semigroup ((<>))
56import Data.Text (Text)
57import qualified Data.Text as Text
58import qualified Data.Text.Lazy as LText
59import qualified Data.Text.Lazy.Builder as Build
60import Data.Text.Manipulate
61import qualified Filesystem.Path.CurrentOS as Path
70import Gen.Types.Schema
72import Prelude hiding (Enum)
73import Text.EDE (Template)
78type Error = LText.Text
79type Path = Path.FilePath
81newtype Version (v :: Symbol) = Version Text
84instance ToJSON (Version v) where
85 toJSON (Version v) = toJSON v
87fver :: Format a (Version v -> a)
88fver = later (\(Version v) -> Build.fromText v)
90type LibraryVer = Version "library"
91type ClientVer = Version "client"
92type CoreVer = Version "core"
94data Versions = Versions
95 { _libraryVersion :: LibraryVer
96 , _clientVersion :: ClientVer
97 , _coreVersion :: CoreVer
104 | Alpha (Maybe Int) (Maybe Char)
105 | Beta (Maybe Int) (Maybe Char)
106 deriving (Eq, Ord, Show)
108data ModelVersion = ModelVersion Double (Maybe Release)
111instance Ord ModelVersion where
112 compare (ModelVersion an ar) (ModelVersion bn br) =
117 (Just x, Just y) -> compare x y
119parseVersion :: Text -> Either String ModelVersion
120parseVersion x = first (mappend (Text.unpack x) . mappend " -> ") $
121 A.parseOnly (preface *> (empty' <|> version) <* A.endOfInput) x
123 empty' = ModelVersion 0 <$> (alpha <|> beta <|> exp')
124 version = ModelVersion
126 <*> (alpha <|> beta <|> sandbox <|> pure Nothing)
128 preface = A.takeWhile (/= '_') *> void (A.char '_') <|> pure ()
129 number = A.takeWhile (/= 'v') *> A.char 'v' *> A.double
131 alpha = A.string "alpha"
132 *> (Alpha <$> optional A.decimal <*> optional A.letter)
135 beta = A.string "beta"
136 *> (Beta <$> optional A.decimal <*> optional A.letter)
139 sandbox = Just Sandbox <$ A.string "sandbox"
140 exp' = Just Sandbox <$ A.string "exp" <* A.decimal
144 , modelPrefix :: Text
145 , modelVersion :: ModelVersion
149instance Eq Model where
150 (==) = on (==) modelPrefix
152instance Ord Model where
154 on compare modelPrefix a b
155 <> on compare (Down . modelVersion) a b
157modelFromPath :: Path -> Model
158modelFromPath x = Model n p v x
161 . Text.intercalate "/"
163 . dropWhile (/= "model")
164 $ Text.split (== '/') p
166 p = toTextIgnore (Path.parent (Path.parent x))
167 v = either error id $ parseVersion (toTextIgnore (Path.dirname x))
169data Templates = Templates
170 { cabalTemplate :: Template
171 , tocTemplate :: Template
172 , readmeTemplate :: Template
173 , typesTemplate :: Template
174 , prodTemplate :: Template
175 , sumTemplate :: Template
176 , actionTemplate :: Template
179data Imports = Imports
181 , typeImports :: [NS]
182 , prodImports :: [NS]
184 , actionImports :: [NS]
187serviceImports :: HasService a b => a -> Imports
188serviceImports s = Imports
189 { tocImports = [preludeNS]
190 , typeImports = sort [preludeNS, prodNS s, sumNS s]
191 , prodImports = sort [preludeNS, sumNS s]
192 , sumImports = [preludeNS]
193 , actionImports = sort [preludeNS, typesNS s]
196tocNS, typesNS, prodNS, sumNS :: HasService a b => a -> NS
197tocNS = mappend "Network.Google" . mkNS . view sCanonicalName
198typesNS = (<> "Types") . tocNS
199prodNS = (<> "Product") . typesNS
200sumNS = (<> "Sum") . typesNS
203preludeNS = "Network.Google.Prelude"
205resourceNS, methodNS :: NS
206resourceNS = "Network.Google.Resource"
207methodNS = "Network.Google.Method"
209exposedModules :: Library -> [NS]
210exposedModules l = sort $
213 : map _actNamespace (_apiResources (_lAPI l))
214 ++ map _actNamespace (_apiMethods (_lAPI l))
216otherModules :: Library -> [NS]
217otherModules s = sort [prodNS s, sumNS s]
219toTextIgnore :: Path -> Text
220toTextIgnore = either id id . Path.toText
222data Library = Library
223 { _lVersions :: Versions
224 , _lService :: Service Global
226 , _lSchemas :: [Data]
231instance HasVersions Library where
234instance HasDescription Library Global where
235 description = lService . description
237instance HasService Library Global where
240instance ToJSON Library where
243 [ "libraryName" .= (l ^. sLibrary)
244 , "libraryTitle" .= renameTitle (l ^. dTitle)
245 , "libraryDescription" .= Desc 4 (l ^. dDescription)
246 , "libraryVersion" .= (l ^. libraryVersion)
247 , "coreVersion" .= (l ^. coreVersion)
248 , "clientVersion" .= (l ^. clientVersion)
249 , "exposedModules" .= exposedModules l
250 , "otherModules" .= otherModules l
254 , "name" .= (l ^. dName)
255 , "version" .= (l ^. dVersion)
256 , "title" .= (l ^. dTitle)
257 , "description" .= (l ^. dDescription)
258 , "documentationLink" .= (l ^. dDocumentationLink)
259 , "labels" .= (l ^. dLabels)
260 , "features" .= (l ^. dFeatures)
261 , "scopes" .= (l ^. dAuth)
264 , "api" .= (l ^. lAPI)
267 , "schemas" .= (l ^. lSchemas)
295 { _additional :: Bool
298 , _schema :: Schema Global
300 , _deriving :: [Derive]
303instance HasInfo Solved where
306 f = lens _schema (\s a -> s { _schema = a })
308monoid :: Solved -> Bool
309monoid = elem DMonoid . _deriving
311setAdditional :: Solved -> Solved
312setAdditional s = setRequired $ s
314 , _type = TMap (TLit Text) (_type s)
317type Seen = Map (CI Text) {- Prefix -} (Set (CI Text)) {- Inhabitants -}
320 { _context :: Service (Fix Schema)
321 , _typed :: Map Global TType
322 , _derived :: Map Global [Derive]
323 , _reserve :: Set Global
324 , _schemas :: Map Global (Schema Global)
325 , _prefixed :: Map Global Prefix
330initial :: Service (Fix Schema) -> Memo
331initial s = Memo s mempty mempty res core mempty mempty mempty
333 -- Top-level schema definitions with ids.
335 . mapMaybe (view iId)
336 $ Map.elems (s ^. dSchemas)
337 -- Types available in Network.Google.Prelude.
339 [ ("Body", SLit requiredInfo RqBody)
340 , ("Stream", SLit requiredInfo RsBody)
341 , ("JSONValue", SLit requiredInfo JSONValue)
346instance HasService Memo (Fix Schema) where
349type AST = ExceptT Error (State Memo)
351reserveType :: Global -> AST Global
353 p <- uses reserve (Set.member g)
359reserveBranches :: AST ()
362 let bs = Set.fromList $ map (CI.mk . global) (Map.keys ss)
363 branches %= Map.insertWith (<>) mempty bs
365reserveFields :: AST ()
368 forM_ (Map.keys ss) $ \(global -> k) -> do
369 let p:ps = splitWords k
371 fields %= Map.insertWith (<>) (CI.mk p) (Set.singleton (CI.mk s))
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list