1+ {-# LANGUAGE CPP #-}
12{-# LANGUAGE DeriveDataTypeable #-}
23{-# LANGUAGE DeriveGeneric #-}
4+ {-# LANGUAGE FlexibleInstances #-}
35{-# LANGUAGE OverloadedStrings #-}
6+ #define UNSAFE 1
47-----------------------------------------------------------------------------
58-- |
69-- License : BSD-3-Clause
710-- Maintainer : Oleg Grenrus <oleg.grenrus@iki.fi>
811--
12+ -- This module also exports
13+ -- @'FromJSON' a => 'FromJSON' ('HM.HashMap' 'Language' a)@
14+ -- orphan-ish instance.
915module GitHub.Data.Repos where
1016
1117import Prelude ()
@@ -15,19 +21,24 @@ import GitHub.Data.Definitions
1521import GitHub.Data.Id (Id )
1622import GitHub.Data.Name (Name )
1723
24+ -- import Control.Arrow (first) -- Data.Bifunctor would be better
1825import Control.DeepSeq (NFData (.. ))
1926import Control.DeepSeq.Generics (genericRnf )
2027import Data.Aeson.Compat (FromJSON (.. ), ToJSON (.. ), object , withObject ,
21- (.:) , (.:?) , (.=) )
28+ withText , (.:) , (.:?) , (.=) )
2229import Data.Binary (Binary )
2330import Data.Data (Data , Typeable )
31+ import Data.Hashable (Hashable (.. ))
32+ import Data.String (IsString (.. ))
2433import Data.Text (Text )
2534import Data.Time (UTCTime )
26- import Data.Vector (Vector )
2735import GHC.Generics (Generic )
2836
2937import qualified Data.HashMap.Strict as HM
30- import qualified Data.Vector as V
38+
39+ #if UNSAFE
40+ import Unsafe.Coerce (unsafeCoerce )
41+ #endif
3142
3243data Repo = Repo {
3344 repoSshUrl :: ! (Maybe Text )
@@ -46,7 +57,7 @@ data Repo = Repo {
4657 ,repoWatchers :: ! (Maybe Int )
4758 ,repoOwner :: ! SimpleOwner
4859 ,repoName :: ! (Name Repo )
49- ,repoLanguage :: ! (Maybe Text )
60+ ,repoLanguage :: ! (Maybe Language )
5061 ,repoMasterBranch :: ! (Maybe Text )
5162 ,repoPushedAt :: ! (Maybe UTCTime ) -- ^ this is Nothing for new repositories
5263 ,repoId :: ! (Id Repo )
@@ -111,20 +122,22 @@ data RepoPublicity
111122 | RepoPublicityMember -- ^ Only repos to which the user is a member but not an owner.
112123 deriving (Show , Eq , Ord , Typeable , Data , Generic )
113124
114- -- | This is only used for the FromJSON instance.
115- data Languages = Languages { getLanguages :: Vector Language }
116- deriving (Show , Data , Typeable , Eq , Ord , Generic )
125+ -- | The value is the number of bytes of code written in that language.
126+ type Languages = HM. HashMap Language Int
117127
118- instance NFData Languages where rnf = genericRnf
119- instance Binary Languages
128+ -- | A programming language.
129+ newtype Language = Language Text
130+ deriving (Show , Data , Typeable , Eq , Ord , Generic )
120131
121- -- | A programming language with the name and number of characters written in
122- -- it.
123- data Language = Language ! Text ! Int
124- deriving (Show , Data , Typeable , Eq , Ord , Generic )
132+ getLanguage :: Language -> Text
133+ getLanguage (Language l) = l
125134
126135instance NFData Language where rnf = genericRnf
127136instance Binary Language
137+ instance Hashable Language where
138+ hashWithSalt salt (Language l) = hashWithSalt salt l
139+ instance IsString Language where
140+ fromString = Language . fromString
128141
129142data Contributor
130143 -- | An existing Github user, with their number of contributions, avatar
@@ -234,8 +247,17 @@ instance FromJSON Contributor where
234247 <*> o .: " id"
235248 <*> o .: " gravatar_id"
236249
237- instance FromJSON Languages where
238- parseJSON = withObject " Languages" $ \ o ->
239- Languages . V. fromList <$>
240- traverse (\ name -> Language name <$> o .: name)
241- (HM. keys o)
250+ instance FromJSON Language where
251+ parseJSON = withText " Language" (pure . Language )
252+
253+ instance FromJSON a => FromJSON (HM. HashMap Language a ) where
254+ parseJSON = fmap mapKeyLanguage . parseJSON
255+ where
256+ mapKeyLanguage :: HM. HashMap Text a -> HM. HashMap Language a
257+ #ifdef UNSAFE
258+ mapKeyLanguage = unsafeCoerce
259+ #else
260+ mapKeyLanguage = mapKey Language
261+ mapKey :: (Eq k2 , Hashable k2 ) => (k1 -> k2 ) -> HM. HashMap k1 a -> HM. HashMap k2 a
262+ mapKey f = HM. fromList . map (first f) . HM. toList
263+ #endif
0 commit comments