twitter-types 0.3.20140801 → 0.4.20140809
raw patch · 8 files changed
+895/−644 lines, 8 filesdep +bytestringdep +directorydep +filepathdep −shakespearePVP ok
version bump matches the API change (PVP)
Dependencies added: bytestring, directory, filepath
Dependencies removed: shakespeare
API changes (from Hackage documentation)
- Web.Twitter.Types: placeUrl :: Place -> Text
- Web.Twitter.Types: searchMetadataRefreshUrl :: SearchMetadata -> URIString
- Web.Twitter.Types: statusFavorite :: Status -> Maybe Bool
- Web.Twitter.Types: statusInReplyTo :: Status -> Maybe StatusId
- Web.Twitter.Types: statusInReplyToUser :: Status -> Maybe UserId
- Web.Twitter.Types: statusRetweet :: Status -> Maybe Status
- Web.Twitter.Types: userFollowers :: User -> Maybe Int
- Web.Twitter.Types: userFriends :: User -> Maybe Int
- Web.Twitter.Types: userLangCode :: User -> Maybe LanguageCode
- Web.Twitter.Types: userTweets :: User -> Maybe Int
- Web.Twitter.Types.Lens: placeUrl :: SimpleLens (Place) (Text)
- Web.Twitter.Types.Lens: searchMetadataRefreshUrl :: SimpleLens (SearchMetadata) (URIString)
- Web.Twitter.Types.Lens: statusFavorite :: SimpleLens (Status) (Maybe Bool)
- Web.Twitter.Types.Lens: statusInReplyTo :: SimpleLens (Status) (Maybe StatusId)
- Web.Twitter.Types.Lens: statusInReplyToUser :: SimpleLens (Status) (Maybe UserId)
- Web.Twitter.Types.Lens: statusRetweet :: SimpleLens (Status) (Maybe Status)
- Web.Twitter.Types.Lens: userFollowers :: SimpleLens (User) (Maybe Int)
- Web.Twitter.Types.Lens: userFriends :: SimpleLens (User) (Maybe Int)
- Web.Twitter.Types.Lens: userLangCode :: SimpleLens (User) (Maybe LanguageCode)
- Web.Twitter.Types.Lens: userTweets :: SimpleLens (User) (Maybe Int)
+ Web.Twitter.Types: Contributor :: UserId -> Text -> Contributor
+ Web.Twitter.Types: contributorId :: Contributor -> UserId
+ Web.Twitter.Types: contributorScreenName :: Contributor -> Text
+ Web.Twitter.Types: data Contributor
+ Web.Twitter.Types: instance Eq Contributor
+ Web.Twitter.Types: instance FromJSON Contributor
+ Web.Twitter.Types: instance Show Contributor
+ Web.Twitter.Types: placeURL :: Place -> Text
+ Web.Twitter.Types: searchMetadataRefreshURL :: SearchMetadata -> URIString
+ Web.Twitter.Types: statusContributors :: Status -> Maybe [Contributor]
+ Web.Twitter.Types: statusCurrentUserRetweet :: Status -> Maybe UserId
+ Web.Twitter.Types: statusFavorited :: Status -> Maybe Bool
+ Web.Twitter.Types: statusFilterLevel :: Status -> Maybe Text
+ Web.Twitter.Types: statusInReplyToScreenName :: Status -> Maybe Text
+ Web.Twitter.Types: statusInReplyToStatusId :: Status -> Maybe StatusId
+ Web.Twitter.Types: statusInReplyToUserId :: Status -> Maybe UserId
+ Web.Twitter.Types: statusRetweeted :: Status -> Maybe Bool
+ Web.Twitter.Types: statusRetweetedStatus :: Status -> Maybe Status
+ Web.Twitter.Types: statusScopes :: Status -> Maybe Object
+ Web.Twitter.Types: statusWithheldCopyright :: Status -> Maybe Bool
+ Web.Twitter.Types: statusWithheldInCountries :: Status -> Maybe [Text]
+ Web.Twitter.Types: statusWithheldScope :: Status -> Maybe Text
+ Web.Twitter.Types: userContributorsEnabled :: User -> Bool
+ Web.Twitter.Types: userDefaultProfile :: User -> Bool
+ Web.Twitter.Types: userDefaultProfileImage :: User -> Bool
+ Web.Twitter.Types: userFavoritesCount :: User -> Int
+ Web.Twitter.Types: userFollowRequestSent :: User -> Maybe Bool
+ Web.Twitter.Types: userFollowersCount :: User -> Int
+ Web.Twitter.Types: userFollowing :: User -> Maybe Bool
+ Web.Twitter.Types: userFriendsCount :: User -> Int
+ Web.Twitter.Types: userGeoEnabled :: User -> Bool
+ Web.Twitter.Types: userIsTranslator :: User -> Bool
+ Web.Twitter.Types: userLang :: User -> LanguageCode
+ Web.Twitter.Types: userListedCount :: User -> Int
+ Web.Twitter.Types: userNotifications :: User -> Maybe Bool
+ Web.Twitter.Types: userProfileBackgroundColor :: User -> Maybe Text
+ Web.Twitter.Types: userProfileBackgroundImageURL :: User -> Maybe URIString
+ Web.Twitter.Types: userProfileBackgroundImageURLHttps :: User -> Maybe URIString
+ Web.Twitter.Types: userProfileBackgroundTile :: User -> Maybe Bool
+ Web.Twitter.Types: userProfileBannerURL :: User -> Maybe URIString
+ Web.Twitter.Types: userProfileImageURLHttps :: User -> Maybe URIString
+ Web.Twitter.Types: userProfileLinkColor :: User -> Text
+ Web.Twitter.Types: userProfileSidebarBorderColor :: User -> Text
+ Web.Twitter.Types: userProfileSidebarFillColor :: User -> Text
+ Web.Twitter.Types: userProfileTextColor :: User -> Text
+ Web.Twitter.Types: userProfileUseBackgroundImage :: User -> Bool
+ Web.Twitter.Types: userShowAllInlineMedia :: User -> Maybe Bool
+ Web.Twitter.Types: userStatusesCount :: User -> Int
+ Web.Twitter.Types: userTimeZone :: User -> Maybe Text
+ Web.Twitter.Types: userUtcOffset :: User -> Maybe Int
+ Web.Twitter.Types: userVerified :: User -> Bool
+ Web.Twitter.Types: userWithheldInCountries :: User -> Maybe Text
+ Web.Twitter.Types: userWithheldScope :: User -> Maybe Text
+ Web.Twitter.Types.Lens: placeURL :: Lens' Place Text
+ Web.Twitter.Types.Lens: searchMetadataRefreshURL :: Lens' SearchMetadata URIString
+ Web.Twitter.Types.Lens: statusContributors :: Lens' Status (Maybe [Contributor])
+ Web.Twitter.Types.Lens: statusCurrentUserRetweet :: Lens' Status (Maybe UserId)
+ Web.Twitter.Types.Lens: statusFavorited :: Lens' Status (Maybe Bool)
+ Web.Twitter.Types.Lens: statusFilterLevel :: Lens' Status (Maybe Text)
+ Web.Twitter.Types.Lens: statusInReplyToScreenName :: Lens' Status (Maybe Text)
+ Web.Twitter.Types.Lens: statusInReplyToStatusId :: Lens' Status (Maybe StatusId)
+ Web.Twitter.Types.Lens: statusInReplyToUserId :: Lens' Status (Maybe UserId)
+ Web.Twitter.Types.Lens: statusRetweeted :: Lens' Status (Maybe Bool)
+ Web.Twitter.Types.Lens: statusRetweetedStatus :: Lens' Status (Maybe Status)
+ Web.Twitter.Types.Lens: statusScopes :: Lens' Status (Maybe Object)
+ Web.Twitter.Types.Lens: statusWithheldCopyright :: Lens' Status (Maybe Bool)
+ Web.Twitter.Types.Lens: statusWithheldInCountries :: Lens' Status (Maybe [Text])
+ Web.Twitter.Types.Lens: statusWithheldScope :: Lens' Status (Maybe Text)
+ Web.Twitter.Types.Lens: userContributorsEnabled :: Lens' User Bool
+ Web.Twitter.Types.Lens: userDefaultProfile :: Lens' User Bool
+ Web.Twitter.Types.Lens: userDefaultProfileImage :: Lens' User Bool
+ Web.Twitter.Types.Lens: userFavoritesCount :: Lens' User Int
+ Web.Twitter.Types.Lens: userFollowRequestSent :: Lens' User (Maybe Bool)
+ Web.Twitter.Types.Lens: userFollowersCount :: Lens' User Int
+ Web.Twitter.Types.Lens: userFollowing :: Lens' User (Maybe Bool)
+ Web.Twitter.Types.Lens: userFriendsCount :: Lens' User Int
+ Web.Twitter.Types.Lens: userGeoEnabled :: Lens' User Bool
+ Web.Twitter.Types.Lens: userIsTranslator :: Lens' User Bool
+ Web.Twitter.Types.Lens: userLang :: Lens' User LanguageCode
+ Web.Twitter.Types.Lens: userListedCount :: Lens' User Int
+ Web.Twitter.Types.Lens: userNotifications :: Lens' User (Maybe Bool)
+ Web.Twitter.Types.Lens: userProfileBackgroundColor :: Lens' User (Maybe Text)
+ Web.Twitter.Types.Lens: userProfileBackgroundImageURL :: Lens' User (Maybe URIString)
+ Web.Twitter.Types.Lens: userProfileBackgroundImageURLHttps :: Lens' User (Maybe URIString)
+ Web.Twitter.Types.Lens: userProfileBackgroundTile :: Lens' User (Maybe Bool)
+ Web.Twitter.Types.Lens: userProfileBannerURL :: Lens' User (Maybe URIString)
+ Web.Twitter.Types.Lens: userProfileImageURLHttps :: Lens' User (Maybe URIString)
+ Web.Twitter.Types.Lens: userProfileLinkColor :: Lens' User Text
+ Web.Twitter.Types.Lens: userProfileSidebarBorderColor :: Lens' User Text
+ Web.Twitter.Types.Lens: userProfileSidebarFillColor :: Lens' User Text
+ Web.Twitter.Types.Lens: userProfileTextColor :: Lens' User Text
+ Web.Twitter.Types.Lens: userProfileUseBackgroundImage :: Lens' User Bool
+ Web.Twitter.Types.Lens: userShowAllInlineMedia :: Lens' User (Maybe Bool)
+ Web.Twitter.Types.Lens: userStatusesCount :: Lens' User Int
+ Web.Twitter.Types.Lens: userTimeZone :: Lens' User (Maybe Text)
+ Web.Twitter.Types.Lens: userUtcOffset :: Lens' User (Maybe Int)
+ Web.Twitter.Types.Lens: userVerified :: Lens' User Bool
+ Web.Twitter.Types.Lens: userWithheldInCountries :: Lens' User (Maybe Text)
+ Web.Twitter.Types.Lens: userWithheldScope :: Lens' User (Maybe Text)
+ Web.Twitter.Types.Lens.Types: type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
+ Web.Twitter.Types.Lens.Types: type Lens' s a = Lens s s a a
- Web.Twitter.Types: Status :: DateString -> StatusId -> Text -> Text -> Bool -> Maybe Entities -> Maybe Entities -> Maybe StatusId -> Maybe UserId -> Maybe Bool -> Maybe Integer -> User -> Maybe Status -> Maybe Place -> Integer -> Maybe Text -> Maybe Bool -> Maybe Coordinates -> Status
+ Web.Twitter.Types: Status :: Maybe [Contributor] -> Maybe Coordinates -> DateString -> Maybe UserId -> Maybe Entities -> Maybe Entities -> Integer -> Maybe Bool -> Maybe Text -> StatusId -> Maybe Text -> Maybe StatusId -> Maybe UserId -> Maybe LanguageCode -> Maybe Place -> Maybe Bool -> Maybe Object -> Integer -> Maybe Bool -> Maybe Status -> Text -> Text -> Bool -> User -> Maybe Bool -> Maybe [Text] -> Maybe Text -> Status
- Web.Twitter.Types: User :: UserId -> UserName -> Text -> Maybe Text -> Maybe Text -> Maybe URIString -> Maybe URIString -> Maybe Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe LanguageCode -> Maybe DateString -> User
+ Web.Twitter.Types: User :: Bool -> DateString -> Bool -> Bool -> Maybe Text -> Int -> Maybe Bool -> Maybe Bool -> Int -> Int -> Bool -> UserId -> Bool -> LanguageCode -> Int -> Maybe Text -> Text -> Maybe Bool -> Maybe Text -> Maybe URIString -> Maybe URIString -> Maybe Bool -> Maybe URIString -> Maybe URIString -> Maybe URIString -> Text -> Text -> Text -> Text -> Bool -> Bool -> Text -> Maybe Bool -> Int -> Maybe Text -> Maybe URIString -> Maybe Int -> Bool -> Maybe Text -> Maybe Text -> User
- Web.Twitter.Types: statusLang :: Status -> Maybe Text
+ Web.Twitter.Types: statusLang :: Status -> Maybe LanguageCode
- Web.Twitter.Types: statusRetweetCount :: Status -> Maybe Integer
+ Web.Twitter.Types: statusRetweetCount :: Status -> Integer
- Web.Twitter.Types: userCreatedAt :: User -> Maybe DateString
+ Web.Twitter.Types: userCreatedAt :: User -> DateString
- Web.Twitter.Types: userName :: User -> UserName
+ Web.Twitter.Types: userName :: User -> Text
- Web.Twitter.Types: userProtected :: User -> Maybe Bool
+ Web.Twitter.Types: userProtected :: User -> Bool
- Web.Twitter.Types.Lens: boundingBoxCoordinates :: SimpleLens (BoundingBox) ([[[Double]]])
+ Web.Twitter.Types.Lens: boundingBoxCoordinates :: Lens' BoundingBox [[[Double]]]
- Web.Twitter.Types.Lens: boundingBoxType :: SimpleLens (BoundingBox) (Text)
+ Web.Twitter.Types.Lens: boundingBoxType :: Lens' BoundingBox Text
- Web.Twitter.Types.Lens: coordinates :: SimpleLens (Coordinates) ([Double])
+ Web.Twitter.Types.Lens: coordinates :: Lens' Coordinates [Double]
- Web.Twitter.Types.Lens: coordinatesType :: SimpleLens (Coordinates) (Text)
+ Web.Twitter.Types.Lens: coordinatesType :: Lens' Coordinates Text
- Web.Twitter.Types.Lens: created_at :: AsStatus s => SimpleLens s DateString
+ Web.Twitter.Types.Lens: created_at :: AsStatus s => Lens' s DateString
- Web.Twitter.Types.Lens: delId :: SimpleLens (Delete) (StatusId)
+ Web.Twitter.Types.Lens: delId :: Lens' Delete StatusId
- Web.Twitter.Types.Lens: delUserId :: SimpleLens (Delete) (UserId)
+ Web.Twitter.Types.Lens: delUserId :: Lens' Delete UserId
- Web.Twitter.Types.Lens: dmCoordinates :: SimpleLens (DirectMessage) (Maybe Coordinates)
+ Web.Twitter.Types.Lens: dmCoordinates :: Lens' DirectMessage (Maybe Coordinates)
- Web.Twitter.Types.Lens: dmCreatedAt :: SimpleLens (DirectMessage) (DateString)
+ Web.Twitter.Types.Lens: dmCreatedAt :: Lens' DirectMessage DateString
- Web.Twitter.Types.Lens: dmId :: SimpleLens (DirectMessage) (StatusId)
+ Web.Twitter.Types.Lens: dmId :: Lens' DirectMessage StatusId
- Web.Twitter.Types.Lens: dmRecipient :: SimpleLens (DirectMessage) (User)
+ Web.Twitter.Types.Lens: dmRecipient :: Lens' DirectMessage User
- Web.Twitter.Types.Lens: dmRecipientId :: SimpleLens (DirectMessage) (UserId)
+ Web.Twitter.Types.Lens: dmRecipientId :: Lens' DirectMessage UserId
- Web.Twitter.Types.Lens: dmRecipientScreeName :: SimpleLens (DirectMessage) (Text)
+ Web.Twitter.Types.Lens: dmRecipientScreeName :: Lens' DirectMessage Text
- Web.Twitter.Types.Lens: dmSender :: SimpleLens (DirectMessage) (User)
+ Web.Twitter.Types.Lens: dmSender :: Lens' DirectMessage User
- Web.Twitter.Types.Lens: dmSenderId :: SimpleLens (DirectMessage) (UserId)
+ Web.Twitter.Types.Lens: dmSenderId :: Lens' DirectMessage UserId
- Web.Twitter.Types.Lens: dmSenderScreenName :: SimpleLens (DirectMessage) (Text)
+ Web.Twitter.Types.Lens: dmSenderScreenName :: Lens' DirectMessage Text
- Web.Twitter.Types.Lens: dmText :: SimpleLens (DirectMessage) (Text)
+ Web.Twitter.Types.Lens: dmText :: Lens' DirectMessage Text
- Web.Twitter.Types.Lens: enHashTags :: SimpleLens (Entities) ([Entity HashTagEntity])
+ Web.Twitter.Types.Lens: enHashTags :: Lens' Entities [Entity HashTagEntity]
- Web.Twitter.Types.Lens: enMedia :: SimpleLens (Entities) ([Entity MediaEntity])
+ Web.Twitter.Types.Lens: enMedia :: Lens' Entities [Entity MediaEntity]
- Web.Twitter.Types.Lens: enURLs :: SimpleLens (Entities) ([Entity URLEntity])
+ Web.Twitter.Types.Lens: enURLs :: Lens' Entities [Entity URLEntity]
- Web.Twitter.Types.Lens: enUserMentions :: SimpleLens (Entities) ([Entity UserEntity])
+ Web.Twitter.Types.Lens: enUserMentions :: Lens' Entities [Entity UserEntity]
- Web.Twitter.Types.Lens: entityBody :: Lens ((Entity) a) ((Entity) b) (a) (b)
+ Web.Twitter.Types.Lens: entityBody :: Lens (Entity a_ao95) (Entity b_ao96) a_ao95 b_ao96
- Web.Twitter.Types.Lens: entityIndices :: SimpleLens (Entity a) (EntityIndices)
+ Web.Twitter.Types.Lens: entityIndices :: Lens' (Entity a_a4Ym) EntityIndices
- Web.Twitter.Types.Lens: evCreatedAt :: SimpleLens (Event) (DateString)
+ Web.Twitter.Types.Lens: evCreatedAt :: Lens' Event DateString
- Web.Twitter.Types.Lens: evEvent :: SimpleLens (Event) (Text)
+ Web.Twitter.Types.Lens: evEvent :: Lens' Event Text
- Web.Twitter.Types.Lens: evSource :: SimpleLens (Event) (EventTarget)
+ Web.Twitter.Types.Lens: evSource :: Lens' Event EventTarget
- Web.Twitter.Types.Lens: evTarget :: SimpleLens (Event) (EventTarget)
+ Web.Twitter.Types.Lens: evTarget :: Lens' Event EventTarget
- Web.Twitter.Types.Lens: evTargetObject :: SimpleLens (Event) (Maybe EventTarget)
+ Web.Twitter.Types.Lens: evTargetObject :: Lens' Event (Maybe EventTarget)
- Web.Twitter.Types.Lens: geolocation :: AsStatus s => SimpleLens s (Maybe Coordinates)
+ Web.Twitter.Types.Lens: geolocation :: AsStatus s => Lens' s (Maybe Coordinates)
- Web.Twitter.Types.Lens: hashTagText :: SimpleLens (HashTagEntity) (Text)
+ Web.Twitter.Types.Lens: hashTagText :: Lens' HashTagEntity Text
- Web.Twitter.Types.Lens: listFullName :: SimpleLens (List) (Text)
+ Web.Twitter.Types.Lens: listFullName :: Lens' List Text
- Web.Twitter.Types.Lens: listId :: SimpleLens (List) (Int)
+ Web.Twitter.Types.Lens: listId :: Lens' List Int
- Web.Twitter.Types.Lens: listMemberCount :: SimpleLens (List) (Int)
+ Web.Twitter.Types.Lens: listMemberCount :: Lens' List Int
- Web.Twitter.Types.Lens: listMode :: SimpleLens (List) (Text)
+ Web.Twitter.Types.Lens: listMode :: Lens' List Text
- Web.Twitter.Types.Lens: listName :: SimpleLens (List) (Text)
+ Web.Twitter.Types.Lens: listName :: Lens' List Text
- Web.Twitter.Types.Lens: listSubscriberCount :: SimpleLens (List) (Int)
+ Web.Twitter.Types.Lens: listSubscriberCount :: Lens' List Int
- Web.Twitter.Types.Lens: listUser :: SimpleLens (List) (User)
+ Web.Twitter.Types.Lens: listUser :: Lens' List User
- Web.Twitter.Types.Lens: meId :: SimpleLens (MediaEntity) (StatusId)
+ Web.Twitter.Types.Lens: meId :: Lens' MediaEntity StatusId
- Web.Twitter.Types.Lens: meMediaURL :: SimpleLens (MediaEntity) (URIString)
+ Web.Twitter.Types.Lens: meMediaURL :: Lens' MediaEntity URIString
- Web.Twitter.Types.Lens: meMediaURLHttps :: SimpleLens (MediaEntity) (URIString)
+ Web.Twitter.Types.Lens: meMediaURLHttps :: Lens' MediaEntity URIString
- Web.Twitter.Types.Lens: meSizes :: SimpleLens (MediaEntity) (HashMap Text MediaSize)
+ Web.Twitter.Types.Lens: meSizes :: Lens' MediaEntity (HashMap Text MediaSize)
- Web.Twitter.Types.Lens: meType :: SimpleLens (MediaEntity) (Text)
+ Web.Twitter.Types.Lens: meType :: Lens' MediaEntity Text
- Web.Twitter.Types.Lens: meURL :: SimpleLens (MediaEntity) (URLEntity)
+ Web.Twitter.Types.Lens: meURL :: Lens' MediaEntity URLEntity
- Web.Twitter.Types.Lens: msHeight :: SimpleLens (MediaSize) (Int)
+ Web.Twitter.Types.Lens: msHeight :: Lens' MediaSize Int
- Web.Twitter.Types.Lens: msResize :: SimpleLens (MediaSize) (Text)
+ Web.Twitter.Types.Lens: msResize :: Lens' MediaSize Text
- Web.Twitter.Types.Lens: msWidth :: SimpleLens (MediaSize) (Int)
+ Web.Twitter.Types.Lens: msWidth :: Lens' MediaSize Int
- Web.Twitter.Types.Lens: name :: AsUser u => SimpleLens u UserName
+ Web.Twitter.Types.Lens: name :: AsUser u => Lens' u UserName
- Web.Twitter.Types.Lens: placeAttributes :: SimpleLens (Place) (HashMap Text Text)
+ Web.Twitter.Types.Lens: placeAttributes :: Lens' Place (HashMap Text Text)
- Web.Twitter.Types.Lens: placeBoundingBox :: SimpleLens (Place) (BoundingBox)
+ Web.Twitter.Types.Lens: placeBoundingBox :: Lens' Place BoundingBox
- Web.Twitter.Types.Lens: placeCountry :: SimpleLens (Place) (Text)
+ Web.Twitter.Types.Lens: placeCountry :: Lens' Place Text
- Web.Twitter.Types.Lens: placeCountryCode :: SimpleLens (Place) (Text)
+ Web.Twitter.Types.Lens: placeCountryCode :: Lens' Place Text
- Web.Twitter.Types.Lens: placeFullName :: SimpleLens (Place) (Text)
+ Web.Twitter.Types.Lens: placeFullName :: Lens' Place Text
- Web.Twitter.Types.Lens: placeId :: SimpleLens (Place) (Text)
+ Web.Twitter.Types.Lens: placeId :: Lens' Place Text
- Web.Twitter.Types.Lens: placeName :: SimpleLens (Place) (Text)
+ Web.Twitter.Types.Lens: placeName :: Lens' Place Text
- Web.Twitter.Types.Lens: placeType :: SimpleLens (Place) (Text)
+ Web.Twitter.Types.Lens: placeType :: Lens' Place Text
- Web.Twitter.Types.Lens: rsCoordinates :: SimpleLens (RetweetedStatus) (Maybe Coordinates)
+ Web.Twitter.Types.Lens: rsCoordinates :: Lens' RetweetedStatus (Maybe Coordinates)
- Web.Twitter.Types.Lens: rsCreatedAt :: SimpleLens (RetweetedStatus) (DateString)
+ Web.Twitter.Types.Lens: rsCreatedAt :: Lens' RetweetedStatus DateString
- Web.Twitter.Types.Lens: rsEntities :: SimpleLens (RetweetedStatus) (Maybe Entities)
+ Web.Twitter.Types.Lens: rsEntities :: Lens' RetweetedStatus (Maybe Entities)
- Web.Twitter.Types.Lens: rsId :: SimpleLens (RetweetedStatus) (StatusId)
+ Web.Twitter.Types.Lens: rsId :: Lens' RetweetedStatus StatusId
- Web.Twitter.Types.Lens: rsRetweetedStatus :: SimpleLens (RetweetedStatus) (Status)
+ Web.Twitter.Types.Lens: rsRetweetedStatus :: Lens' RetweetedStatus Status
- Web.Twitter.Types.Lens: rsSource :: SimpleLens (RetweetedStatus) (Text)
+ Web.Twitter.Types.Lens: rsSource :: Lens' RetweetedStatus Text
- Web.Twitter.Types.Lens: rsText :: SimpleLens (RetweetedStatus) (Text)
+ Web.Twitter.Types.Lens: rsText :: Lens' RetweetedStatus Text
- Web.Twitter.Types.Lens: rsTruncated :: SimpleLens (RetweetedStatus) (Bool)
+ Web.Twitter.Types.Lens: rsTruncated :: Lens' RetweetedStatus Bool
- Web.Twitter.Types.Lens: rsUser :: SimpleLens (RetweetedStatus) (User)
+ Web.Twitter.Types.Lens: rsUser :: Lens' RetweetedStatus User
- Web.Twitter.Types.Lens: screen_name :: AsUser u => SimpleLens u Text
+ Web.Twitter.Types.Lens: screen_name :: AsUser u => Lens' u Text
- Web.Twitter.Types.Lens: searchMetadataCompletedIn :: SimpleLens (SearchMetadata) (Maybe Float)
+ Web.Twitter.Types.Lens: searchMetadataCompletedIn :: Lens' SearchMetadata (Maybe Float)
- Web.Twitter.Types.Lens: searchMetadataCount :: SimpleLens (SearchMetadata) (Int)
+ Web.Twitter.Types.Lens: searchMetadataCount :: Lens' SearchMetadata Int
- Web.Twitter.Types.Lens: searchMetadataMaxId :: SimpleLens (SearchMetadata) (StatusId)
+ Web.Twitter.Types.Lens: searchMetadataMaxId :: Lens' SearchMetadata StatusId
- Web.Twitter.Types.Lens: searchMetadataMaxIdStr :: SimpleLens (SearchMetadata) (String)
+ Web.Twitter.Types.Lens: searchMetadataMaxIdStr :: Lens' SearchMetadata String
- Web.Twitter.Types.Lens: searchMetadataNextResults :: SimpleLens (SearchMetadata) (Maybe URIString)
+ Web.Twitter.Types.Lens: searchMetadataNextResults :: Lens' SearchMetadata (Maybe URIString)
- Web.Twitter.Types.Lens: searchMetadataQuery :: SimpleLens (SearchMetadata) (String)
+ Web.Twitter.Types.Lens: searchMetadataQuery :: Lens' SearchMetadata String
- Web.Twitter.Types.Lens: searchMetadataSinceId :: SimpleLens (SearchMetadata) (StatusId)
+ Web.Twitter.Types.Lens: searchMetadataSinceId :: Lens' SearchMetadata StatusId
- Web.Twitter.Types.Lens: searchMetadataSinceIdStr :: SimpleLens (SearchMetadata) (String)
+ Web.Twitter.Types.Lens: searchMetadataSinceIdStr :: Lens' SearchMetadata String
- Web.Twitter.Types.Lens: searchResultSearchMetadata :: SimpleLens (SearchResult body) (SearchMetadata)
+ Web.Twitter.Types.Lens: searchResultSearchMetadata :: Lens' (SearchResult body_a4Z8) SearchMetadata
- Web.Twitter.Types.Lens: searchResultStatuses :: Lens ((SearchResult) a) ((SearchResult) b) (a) (b)
+ Web.Twitter.Types.Lens: searchResultStatuses :: Lens (SearchResult a_anNI) (SearchResult b_anNJ) a_anNI b_anNJ
- Web.Twitter.Types.Lens: searchStatusCoordinates :: SimpleLens (SearchStatus) (Maybe Coordinates)
+ Web.Twitter.Types.Lens: searchStatusCoordinates :: Lens' SearchStatus (Maybe Coordinates)
- Web.Twitter.Types.Lens: searchStatusCreatedAt :: SimpleLens (SearchStatus) (DateString)
+ Web.Twitter.Types.Lens: searchStatusCreatedAt :: Lens' SearchStatus DateString
- Web.Twitter.Types.Lens: searchStatusId :: SimpleLens (SearchStatus) (StatusId)
+ Web.Twitter.Types.Lens: searchStatusId :: Lens' SearchStatus StatusId
- Web.Twitter.Types.Lens: searchStatusSource :: SimpleLens (SearchStatus) (Text)
+ Web.Twitter.Types.Lens: searchStatusSource :: Lens' SearchStatus Text
- Web.Twitter.Types.Lens: searchStatusText :: SimpleLens (SearchStatus) (Text)
+ Web.Twitter.Types.Lens: searchStatusText :: Lens' SearchStatus Text
- Web.Twitter.Types.Lens: searchStatusUser :: SimpleLens (SearchStatus) (User)
+ Web.Twitter.Types.Lens: searchStatusUser :: Lens' SearchStatus User
- Web.Twitter.Types.Lens: statusCoordinates :: SimpleLens (Status) (Maybe Coordinates)
+ Web.Twitter.Types.Lens: statusCoordinates :: Lens' Status (Maybe Coordinates)
- Web.Twitter.Types.Lens: statusCreatedAt :: SimpleLens (Status) (DateString)
+ Web.Twitter.Types.Lens: statusCreatedAt :: Lens' Status DateString
- Web.Twitter.Types.Lens: statusEntities :: SimpleLens (Status) (Maybe Entities)
+ Web.Twitter.Types.Lens: statusEntities :: Lens' Status (Maybe Entities)
- Web.Twitter.Types.Lens: statusExtendedEntities :: SimpleLens (Status) (Maybe Entities)
+ Web.Twitter.Types.Lens: statusExtendedEntities :: Lens' Status (Maybe Entities)
- Web.Twitter.Types.Lens: statusFavoriteCount :: SimpleLens (Status) (Integer)
+ Web.Twitter.Types.Lens: statusFavoriteCount :: Lens' Status Integer
- Web.Twitter.Types.Lens: statusId :: SimpleLens (Status) (StatusId)
+ Web.Twitter.Types.Lens: statusId :: Lens' Status StatusId
- Web.Twitter.Types.Lens: statusLang :: SimpleLens (Status) (Maybe Text)
+ Web.Twitter.Types.Lens: statusLang :: Lens' Status (Maybe LanguageCode)
- Web.Twitter.Types.Lens: statusPlace :: SimpleLens (Status) (Maybe Place)
+ Web.Twitter.Types.Lens: statusPlace :: Lens' Status (Maybe Place)
- Web.Twitter.Types.Lens: statusPossiblySensitive :: SimpleLens (Status) (Maybe Bool)
+ Web.Twitter.Types.Lens: statusPossiblySensitive :: Lens' Status (Maybe Bool)
- Web.Twitter.Types.Lens: statusRetweetCount :: SimpleLens (Status) (Maybe Integer)
+ Web.Twitter.Types.Lens: statusRetweetCount :: Lens' Status Integer
- Web.Twitter.Types.Lens: statusSource :: SimpleLens (Status) (Text)
+ Web.Twitter.Types.Lens: statusSource :: Lens' Status Text
- Web.Twitter.Types.Lens: statusText :: SimpleLens (Status) (Text)
+ Web.Twitter.Types.Lens: statusText :: Lens' Status Text
- Web.Twitter.Types.Lens: statusTruncated :: SimpleLens (Status) (Bool)
+ Web.Twitter.Types.Lens: statusTruncated :: Lens' Status Bool
- Web.Twitter.Types.Lens: statusUser :: SimpleLens (Status) (User)
+ Web.Twitter.Types.Lens: statusUser :: Lens' Status User
- Web.Twitter.Types.Lens: status_id :: AsStatus s => SimpleLens s StatusId
+ Web.Twitter.Types.Lens: status_id :: AsStatus s => Lens' s StatusId
- Web.Twitter.Types.Lens: text :: AsStatus s => SimpleLens s Text
+ Web.Twitter.Types.Lens: text :: AsStatus s => Lens' s Text
- Web.Twitter.Types.Lens: ueDisplay :: SimpleLens (URLEntity) (Text)
+ Web.Twitter.Types.Lens: ueDisplay :: Lens' URLEntity Text
- Web.Twitter.Types.Lens: ueExpanded :: SimpleLens (URLEntity) (URIString)
+ Web.Twitter.Types.Lens: ueExpanded :: Lens' URLEntity URIString
- Web.Twitter.Types.Lens: ueURL :: SimpleLens (URLEntity) (URIString)
+ Web.Twitter.Types.Lens: ueURL :: Lens' URLEntity URIString
- Web.Twitter.Types.Lens: user :: AsStatus s => SimpleLens s User
+ Web.Twitter.Types.Lens: user :: AsStatus s => Lens' s User
- Web.Twitter.Types.Lens: userCreatedAt :: SimpleLens (User) (Maybe DateString)
+ Web.Twitter.Types.Lens: userCreatedAt :: Lens' User DateString
- Web.Twitter.Types.Lens: userDescription :: SimpleLens (User) (Maybe Text)
+ Web.Twitter.Types.Lens: userDescription :: Lens' User (Maybe Text)
- Web.Twitter.Types.Lens: userEntityUserId :: SimpleLens (UserEntity) (UserId)
+ Web.Twitter.Types.Lens: userEntityUserId :: Lens' UserEntity UserId
- Web.Twitter.Types.Lens: userEntityUserName :: SimpleLens (UserEntity) (UserName)
+ Web.Twitter.Types.Lens: userEntityUserName :: Lens' UserEntity UserName
- Web.Twitter.Types.Lens: userEntityUserScreenName :: SimpleLens (UserEntity) (Text)
+ Web.Twitter.Types.Lens: userEntityUserScreenName :: Lens' UserEntity Text
- Web.Twitter.Types.Lens: userId :: SimpleLens (User) (UserId)
+ Web.Twitter.Types.Lens: userId :: Lens' User UserId
- Web.Twitter.Types.Lens: userLocation :: SimpleLens (User) (Maybe Text)
+ Web.Twitter.Types.Lens: userLocation :: Lens' User (Maybe Text)
- Web.Twitter.Types.Lens: userName :: SimpleLens (User) (UserName)
+ Web.Twitter.Types.Lens: userName :: Lens' User Text
- Web.Twitter.Types.Lens: userProfileImageURL :: SimpleLens (User) (Maybe URIString)
+ Web.Twitter.Types.Lens: userProfileImageURL :: Lens' User (Maybe URIString)
- Web.Twitter.Types.Lens: userProtected :: SimpleLens (User) (Maybe Bool)
+ Web.Twitter.Types.Lens: userProtected :: Lens' User Bool
- Web.Twitter.Types.Lens: userScreenName :: SimpleLens (User) (Text)
+ Web.Twitter.Types.Lens: userScreenName :: Lens' User Text
- Web.Twitter.Types.Lens: userURL :: SimpleLens (User) (Maybe URIString)
+ Web.Twitter.Types.Lens: userURL :: Lens' User (Maybe URIString)
- Web.Twitter.Types.Lens: user_id :: AsUser u => SimpleLens u UserId
+ Web.Twitter.Types.Lens: user_id :: AsUser u => Lens' u UserId
Files
- .travis.yml +47/−4
- Web/Twitter/Types.hs +418/−336
- Web/Twitter/Types/Lens.hs +127/−250
- Web/Twitter/Types/Lens/TH.hs +62/−0
- Web/Twitter/Types/Lens/Types.hs +14/−0
- tests/Fixtures.hs +27/−17
- tests/TypesTest.hs +189/−34
- twitter-types.cabal +11/−3
.travis.yml view
@@ -1,8 +1,51 @@ language: haskell++env:+ matrix:+ - GHCVER=7.4.2+ - GHCVER=7.6.3+ - GHCVER=7.8.3 USE_COVERALLS=1+ - GHCVER=head++matrix:+ allow_failures:+ - env: GHCVER=head+ before_install:- - cabal install hpc-coveralls+ - |+ if [ $GHCVER = `ghc --numeric-version` ]; then+ echo "use system ghc: `which ghc` `ghc --numeric-version`"+ else+ travis_retry sudo add-apt-repository -y ppa:hvr/ghc+ travis_retry sudo apt-get update+ travis_retry sudo apt-get install -y --force-yes cabal-install-1.18 ghc-$GHCVER+ export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/1.18/bin:$PATH+ echo "use ppa:hvr/ghc: `which ghc` `ghc --numeric-version`"+ fi++install:+ - export PATH=$HOME/.cabal/bin:$PATH+ - which cabal+ - travis_retry cabal update+ - cabal install happy+ - cabal install --only-dependencies --enable-tests+ - "[ -n \"$USE_COVERALLS\" ] && travis_retry cabal install hpc-coveralls || true"+ - ghc-pkg list+ script:- - cabal configure --enable-tests --enable-library-coverage && cabal build- - run-cabal-test+ - |+ if [ -n "$USE_COVERALLS" ]; then+ cabal configure --enable-tests --enable-library-coverage $CABAL_FLAGS+ else+ cabal configure --enable-tests $CABAL_FLAGS+ fi+ - cabal build+ - |+ if [ -n "$USE_COVERALLS" ]; then+ run-cabal-test --show-details=always+ else+ cabal test --show-details=always+ fi+ after_script:- - hpc-coveralls tests+ - "[ -n \"$USE_COVERALLS\" ] && hpc-coveralls --exclude-dir=tests tests || true"
Web/Twitter/Types.hs view
@@ -31,6 +31,7 @@ , Coordinates(..) , Place(..) , BoundingBox(..)+ , Contributor(..) , checkError ) where@@ -61,180 +62,197 @@ checkError :: Object -> Parser () checkError o = do- err <- o .:? "error"- case err of- Just msg -> fail msg- Nothing -> return ()+ err <- o .:? "error"+ case err of+ Just msg -> fail msg+ Nothing -> return () instance FromJSON StreamingAPI where- parseJSON v@(Object o) =- SRetweetedStatus <$> js <|>- SStatus <$> js <|>- SEvent <$> js <|>- SDelete <$> js <|>- SFriends <$> (o .: "friends") <|>- return (SUnknown v)- where- js :: FromJSON a => Parser a- js = parseJSON v- parseJSON _ = mzero+ parseJSON v@(Object o) =+ SRetweetedStatus <$> js <|>+ SStatus <$> js <|>+ SEvent <$> js <|>+ SDelete <$> js <|>+ SFriends <$> (o .: "friends") <|>+ return (SUnknown v)+ where+ js :: FromJSON a => Parser a+ js = parseJSON v+ parseJSON _ = mzero -data Status =- Status- { statusCreatedAt :: DateString- , statusId :: StatusId- , statusText :: Text- , statusSource :: Text- , statusTruncated :: Bool- , statusEntities :: Maybe Entities- , statusExtendedEntities :: Maybe Entities- , statusInReplyTo :: Maybe StatusId- , statusInReplyToUser :: Maybe UserId- , statusFavorite :: Maybe Bool- , statusRetweetCount :: Maybe Integer- , statusUser :: User- , statusRetweet :: Maybe Status- , statusPlace :: Maybe Place- , statusFavoriteCount :: Integer- , statusLang :: Maybe Text- , statusPossiblySensitive :: Maybe Bool- , statusCoordinates :: Maybe Coordinates- } deriving (Show, Eq)+data Status = Status+ { statusContributors :: Maybe [Contributor]+ , statusCoordinates :: Maybe Coordinates+ , statusCreatedAt :: DateString+ , statusCurrentUserRetweet :: Maybe UserId+ , statusEntities :: Maybe Entities+ , statusExtendedEntities :: Maybe Entities+ , statusFavoriteCount :: Integer+ , statusFavorited :: Maybe Bool+ , statusFilterLevel :: Maybe Text+ , statusId :: StatusId+ , statusInReplyToScreenName :: Maybe Text+ , statusInReplyToStatusId :: Maybe StatusId+ , statusInReplyToUserId :: Maybe UserId+ , statusLang :: Maybe LanguageCode+ , statusPlace :: Maybe Place+ , statusPossiblySensitive :: Maybe Bool+ , statusScopes :: Maybe Object+ , statusRetweetCount :: Integer+ , statusRetweeted :: Maybe Bool+ , statusRetweetedStatus :: Maybe Status+ , statusSource :: Text+ , statusText :: Text+ , statusTruncated :: Bool+ , statusUser :: User+ , statusWithheldCopyright :: Maybe Bool+ , statusWithheldInCountries :: Maybe [Text]+ , statusWithheldScope :: Maybe Text+ } deriving (Show, Eq) instance FromJSON Status where- parseJSON (Object o) = checkError o >>- Status <$> o .: "created_at"- <*> o .: "id"- <*> o .: "text"- <*> o .: "source"- <*> o .: "truncated"- <*> o .:? "entities"- <*> o .:? "extended_entities"- <*> o .:? "in_reply_to_status_id"- <*> o .:? "in_reply_to_user_id"- <*> o .:? "favorited"- <*> o .:? "retweet_count"- <*> o .: "user"- <*> o .:? "retweeted_status"- <*> o .:? "place"- <*> o .:? "favorite_count" .!= 0- <*> o .:? "lang"- <*> o .:? "possibly_sensitive"- <*> o .:? "coordinates"- parseJSON _ = mzero+ parseJSON (Object o) = checkError o >>+ Status <$> o .:? "contributors"+ <*> o .:? "coordinates"+ <*> o .: "created_at"+ <*> ((o .: "current_user_retweet" >>= (.: "id")) <|> return Nothing)+ <*> o .:? "entities"+ <*> o .:? "extended_entities"+ <*> o .:? "favorite_count" .!= 0+ <*> o .:? "favorited"+ <*> o .:? "filter_level"+ <*> o .: "id"+ <*> o .:? "in_reply_to_screen_name"+ <*> o .:? "in_reply_to_status_id"+ <*> o .:? "in_reply_to_user_id"+ <*> o .:? "lang"+ <*> o .:? "place"+ <*> o .:? "possibly_sensitive"+ <*> o .:? "scopes"+ <*> o .:? "retweet_count" .!= 0+ <*> o .:? "retweeted"+ <*> o .:? "retweeted_status"+ <*> o .: "source"+ <*> o .: "text"+ <*> o .: "truncated"+ <*> o .: "user"+ <*> o .:? "withheld_copyright"+ <*> o .:? "withheld_in_countries"+ <*> o .:? "withheld_scope"+ parseJSON _ = mzero data SearchResult body =- SearchResult- { searchResultStatuses :: body- , searchResultSearchMetadata :: SearchMetadata- } deriving (Show, Eq)+ SearchResult+ { searchResultStatuses :: body+ , searchResultSearchMetadata :: SearchMetadata+ } deriving (Show, Eq) instance FromJSON body => FromJSON (SearchResult body) where- parseJSON (Object o) = checkError o >>- SearchResult <$> o .: "statuses"- <*> o .: "search_metadata"- parseJSON _ = mzero+ parseJSON (Object o) = checkError o >>+ SearchResult <$> o .: "statuses"+ <*> o .: "search_metadata"+ parseJSON _ = mzero data SearchStatus =- SearchStatus- { searchStatusCreatedAt :: DateString- , searchStatusId :: StatusId- , searchStatusText :: Text- , searchStatusSource :: Text- , searchStatusUser :: User- , searchStatusCoordinates :: Maybe Coordinates- } deriving (Show, Eq)+ SearchStatus+ { searchStatusCreatedAt :: DateString+ , searchStatusId :: StatusId+ , searchStatusText :: Text+ , searchStatusSource :: Text+ , searchStatusUser :: User+ , searchStatusCoordinates :: Maybe Coordinates+ } deriving (Show, Eq) instance FromJSON SearchStatus where- parseJSON (Object o) = checkError o >>- SearchStatus <$> o .: "created_at"- <*> o .: "id"- <*> o .: "text"- <*> o .: "source"- <*> o .: "user"- <*> o .:? "coordinates"- parseJSON _ = mzero+ parseJSON (Object o) = checkError o >>+ SearchStatus <$> o .: "created_at"+ <*> o .: "id"+ <*> o .: "text"+ <*> o .: "source"+ <*> o .: "user"+ <*> o .:? "coordinates"+ parseJSON _ = mzero data SearchMetadata =- SearchMetadata- { searchMetadataMaxId :: StatusId- , searchMetadataSinceId :: StatusId- , searchMetadataRefreshUrl :: URIString- , searchMetadataNextResults :: Maybe URIString- , searchMetadataCount :: Int- , searchMetadataCompletedIn :: Maybe Float- , searchMetadataSinceIdStr :: String- , searchMetadataQuery :: String- , searchMetadataMaxIdStr :: String- } deriving (Show, Eq)+ SearchMetadata+ { searchMetadataMaxId :: StatusId+ , searchMetadataSinceId :: StatusId+ , searchMetadataRefreshURL :: URIString+ , searchMetadataNextResults :: Maybe URIString+ , searchMetadataCount :: Int+ , searchMetadataCompletedIn :: Maybe Float+ , searchMetadataSinceIdStr :: String+ , searchMetadataQuery :: String+ , searchMetadataMaxIdStr :: String+ } deriving (Show, Eq) instance FromJSON SearchMetadata where- parseJSON (Object o) = checkError o >>- SearchMetadata <$> o .: "max_id"- <*> o .: "since_id"- <*> o .: "refresh_url"- <*> o .:? "next_results"- <*> o .: "count"- <*> o .:? "completed_in"- <*> o .: "since_id_str"- <*> o .: "query"- <*> o .: "max_id_str"- parseJSON _ = mzero+ parseJSON (Object o) = checkError o >>+ SearchMetadata <$> o .: "max_id"+ <*> o .: "since_id"+ <*> o .: "refresh_url"+ <*> o .:? "next_results"+ <*> o .: "count"+ <*> o .:? "completed_in"+ <*> o .: "since_id_str"+ <*> o .: "query"+ <*> o .: "max_id_str"+ parseJSON _ = mzero data RetweetedStatus =- RetweetedStatus- { rsCreatedAt :: DateString- , rsId :: StatusId- , rsText :: Text- , rsSource :: Text- , rsTruncated :: Bool- , rsEntities :: Maybe Entities- , rsUser :: User- , rsRetweetedStatus :: Status- , rsCoordinates :: Maybe Coordinates- } deriving (Show, Eq)+ RetweetedStatus+ { rsCreatedAt :: DateString+ , rsId :: StatusId+ , rsText :: Text+ , rsSource :: Text+ , rsTruncated :: Bool+ , rsEntities :: Maybe Entities+ , rsUser :: User+ , rsRetweetedStatus :: Status+ , rsCoordinates :: Maybe Coordinates+ } deriving (Show, Eq) instance FromJSON RetweetedStatus where- parseJSON (Object o) = checkError o >>- RetweetedStatus <$> o .: "created_at"- <*> o .: "id"- <*> o .: "text"- <*> o .: "source"- <*> o .: "truncated"- <*> o .:? "entities"- <*> o .: "user"- <*> o .: "retweeted_status"- <*> o .:? "coordinates"- parseJSON _ = mzero+ parseJSON (Object o) = checkError o >>+ RetweetedStatus <$> o .: "created_at"+ <*> o .: "id"+ <*> o .: "text"+ <*> o .: "source"+ <*> o .: "truncated"+ <*> o .:? "entities"+ <*> o .: "user"+ <*> o .: "retweeted_status"+ <*> o .:? "coordinates"+ parseJSON _ = mzero data DirectMessage =- DirectMessage- { dmCreatedAt :: DateString- , dmSenderScreenName :: Text- , dmSender :: User- , dmText :: Text- , dmRecipientScreeName :: Text- , dmId :: StatusId- , dmRecipient :: User- , dmRecipientId :: UserId- , dmSenderId :: UserId- , dmCoordinates :: Maybe Coordinates- } deriving (Show, Eq)+ DirectMessage+ { dmCreatedAt :: DateString+ , dmSenderScreenName :: Text+ , dmSender :: User+ , dmText :: Text+ , dmRecipientScreeName :: Text+ , dmId :: StatusId+ , dmRecipient :: User+ , dmRecipientId :: UserId+ , dmSenderId :: UserId+ , dmCoordinates :: Maybe Coordinates+ } deriving (Show, Eq) instance FromJSON DirectMessage where- parseJSON (Object o) = checkError o >>- DirectMessage <$> o .: "created_at"- <*> o .: "sender_screen_name"- <*> o .: "sender"- <*> o .: "text"- <*> o .: "recipient_screen_name"- <*> o .: "id"- <*> o .: "recipient"- <*> o .: "recipient_id"- <*> o .: "sender_id"- <*> o .:? "coordinates"- parseJSON _ = mzero+ parseJSON (Object o) = checkError o >>+ DirectMessage <$> o .: "created_at"+ <*> o .: "sender_screen_name"+ <*> o .: "sender"+ <*> o .: "text"+ <*> o .: "recipient_screen_name"+ <*> o .: "id"+ <*> o .: "recipient"+ <*> o .: "recipient_id"+ <*> o .: "sender_id"+ <*> o .:? "coordinates"+ parseJSON _ = mzero data EventType = Favorite | Unfavorite | ListCreated | ListUpdated | ListMemberAdded@@ -245,238 +263,291 @@ deriving (Show, Eq) instance FromJSON EventTarget where- parseJSON v@(Object o) = checkError o >>- ETUser <$> parseJSON v <|>- ETStatus <$> parseJSON v <|>- ETList <$> parseJSON v <|>- return (ETUnknown v)- parseJSON _ = mzero+ parseJSON v@(Object o) = checkError o >>+ ETUser <$> parseJSON v <|>+ ETStatus <$> parseJSON v <|>+ ETList <$> parseJSON v <|>+ return (ETUnknown v)+ parseJSON _ = mzero data Event =- Event- { evCreatedAt :: DateString- , evTargetObject :: Maybe EventTarget- , evEvent :: Text- , evTarget :: EventTarget- , evSource :: EventTarget- } deriving (Show, Eq)+ Event+ { evCreatedAt :: DateString+ , evTargetObject :: Maybe EventTarget+ , evEvent :: Text+ , evTarget :: EventTarget+ , evSource :: EventTarget+ } deriving (Show, Eq) instance FromJSON Event where- parseJSON (Object o) = checkError o >>- Event <$> o .: "created_at"- <*> o .:? "target_object"- <*> o .: "event"- <*> o .: "target"- <*> o .: "source"- parseJSON _ = mzero+ parseJSON (Object o) = checkError o >>+ Event <$> o .: "created_at"+ <*> o .:? "target_object"+ <*> o .: "event"+ <*> o .: "target"+ <*> o .: "source"+ parseJSON _ = mzero data Delete =- Delete- { delId :: StatusId- , delUserId :: UserId- } deriving (Show, Eq)+ Delete+ { delId :: StatusId+ , delUserId :: UserId+ } deriving (Show, Eq) instance FromJSON Delete where- parseJSON (Object o) = checkError o >> do- s <- o .: "delete" >>= (.: "status")- Delete <$> s .: "id"- <*> s .: "user_id"- parseJSON _ = mzero+ parseJSON (Object o) = checkError o >> do+ s <- o .: "delete" >>= (.: "status")+ Delete <$> s .: "id"+ <*> s .: "user_id"+ parseJSON _ = mzero -data User =- User- { userId :: UserId- , userName :: UserName- , userScreenName :: Text- , userDescription :: Maybe Text- , userLocation :: Maybe Text- , userProfileImageURL :: Maybe URIString- , userURL :: Maybe URIString- , userProtected :: Maybe Bool- , userFollowers :: Maybe Int- , userFriends :: Maybe Int- , userTweets :: Maybe Int- , userLangCode :: Maybe LanguageCode- , userCreatedAt :: Maybe DateString- } deriving (Show, Eq)+data User = User+ { userContributorsEnabled :: Bool+ , userCreatedAt :: DateString+ , userDefaultProfile :: Bool+ , userDefaultProfileImage :: Bool+ , userDescription :: Maybe Text+ , userFavoritesCount :: Int+ , userFollowRequestSent :: Maybe Bool+ , userFollowing :: Maybe Bool+ , userFollowersCount :: Int+ , userFriendsCount :: Int+ , userGeoEnabled :: Bool+ , userId :: UserId+ , userIsTranslator :: Bool+ , userLang :: LanguageCode+ , userListedCount :: Int+ , userLocation :: Maybe Text+ , userName :: Text+ , userNotifications :: Maybe Bool+ , userProfileBackgroundColor :: Maybe Text+ , userProfileBackgroundImageURL :: Maybe URIString+ , userProfileBackgroundImageURLHttps :: Maybe URIString+ , userProfileBackgroundTile :: Maybe Bool+ , userProfileBannerURL :: Maybe URIString+ , userProfileImageURL :: Maybe URIString+ , userProfileImageURLHttps :: Maybe URIString+ , userProfileLinkColor :: Text+ , userProfileSidebarBorderColor :: Text+ , userProfileSidebarFillColor :: Text+ , userProfileTextColor :: Text+ , userProfileUseBackgroundImage :: Bool+ , userProtected :: Bool+ , userScreenName :: Text+ , userShowAllInlineMedia :: Maybe Bool+ , userStatusesCount :: Int+ , userTimeZone :: Maybe Text+ , userURL :: Maybe URIString+ , userUtcOffset :: Maybe Int+ , userVerified :: Bool+ , userWithheldInCountries :: Maybe Text+ , userWithheldScope :: Maybe Text+ } deriving (Show, Eq) instance FromJSON User where- parseJSON (Object o) = checkError o >>- User <$> o .: "id"- <*> o .: "name"- <*> o .: "screen_name"- <*> o .:? "description"- <*> o .:? "location"- <*> o .:? "profile_image_url"- <*> o .:? "url"- <*> o .:? "protected"- <*> o .:? "followers_count"- <*> o .:? "friends_count"- <*> o .:? "statuses_count"- <*> o .:? "lang"- <*> o .:? "created_at"- parseJSON _ = mzero+ parseJSON (Object o) = checkError o >>+ User <$> o .: "contributors_enabled"+ <*> o .: "created_at"+ <*> o .: "default_profile"+ <*> o .: "default_profile_image"+ <*> o .:? "description"+ <*> o .: "favourites_count"+ <*> o .:? "follow_request_sent"+ <*> o .:? "following"+ <*> o .: "followers_count"+ <*> o .: "friends_count"+ <*> o .: "geo_enabled"+ <*> o .: "id"+ <*> o .: "is_translator"+ <*> o .: "lang"+ <*> o .: "listed_count"+ <*> o .:? "location"+ <*> o .: "name"+ <*> o .:? "notifications"+ <*> o .:? "profile_background_color"+ <*> o .:? "profile_background_image_url"+ <*> o .:? "profile_background_image_url_https"+ <*> o .:? "profile_background_tile"+ <*> o .:? "profile_banner_url"+ <*> o .:? "profile_image_url"+ <*> o .:? "profile_image_url_https"+ <*> o .: "profile_link_color"+ <*> o .: "profile_sidebar_border_color"+ <*> o .: "profile_sidebar_fill_color"+ <*> o .: "profile_text_color"+ <*> o .: "profile_use_background_image"+ <*> o .: "protected"+ <*> o .: "screen_name"+ <*> o .:? "show_all_inline_media"+ <*> o .: "statuses_count"+ <*> o .:? "time_zone"+ <*> o .:? "url"+ <*> o .:? "utc_offset"+ <*> o .: "verified"+ <*> o .:? "withheld_in_countries"+ <*> o .:? "withheld_scope"+ parseJSON _ = mzero data List =- List- { listId :: Int- , listName :: Text- , listFullName :: Text- , listMemberCount :: Int- , listSubscriberCount :: Int- , listMode :: Text- , listUser :: User- } deriving (Show, Eq)+ List+ { listId :: Int+ , listName :: Text+ , listFullName :: Text+ , listMemberCount :: Int+ , listSubscriberCount :: Int+ , listMode :: Text+ , listUser :: User+ } deriving (Show, Eq) instance FromJSON List where- parseJSON (Object o) = checkError o >>- List <$> o .: "id"- <*> o .: "name"- <*> o .: "full_name"- <*> o .: "member_count"- <*> o .: "subscriber_count"- <*> o .: "mode"- <*> o .: "user"- parseJSON _ = mzero+ parseJSON (Object o) = checkError o >>+ List <$> o .: "id"+ <*> o .: "name"+ <*> o .: "full_name"+ <*> o .: "member_count"+ <*> o .: "subscriber_count"+ <*> o .: "mode"+ <*> o .: "user"+ parseJSON _ = mzero data HashTagEntity =- HashTagEntity- { hashTagText :: Text -- ^ The Hashtag text- } deriving (Show, Eq)+ HashTagEntity+ { hashTagText :: Text -- ^ The Hashtag text+ } deriving (Show, Eq) instance FromJSON HashTagEntity where- parseJSON (Object o) =- HashTagEntity <$> o .: "text"- parseJSON _ = mzero+ parseJSON (Object o) =+ HashTagEntity <$> o .: "text"+ parseJSON _ = mzero data UserEntity =- UserEntity- { userEntityUserId :: UserId- , userEntityUserName :: UserName- , userEntityUserScreenName :: Text- } deriving (Show, Eq)+ UserEntity+ { userEntityUserId :: UserId+ , userEntityUserName :: UserName+ , userEntityUserScreenName :: Text+ } deriving (Show, Eq) instance FromJSON UserEntity where- parseJSON (Object o) =- UserEntity <$> o .: "id"- <*> o .: "name"- <*> o .: "screen_name"- parseJSON _ = mzero+ parseJSON (Object o) =+ UserEntity <$> o .: "id"+ <*> o .: "name"+ <*> o .: "screen_name"+ parseJSON _ = mzero data URLEntity =- URLEntity- { ueURL :: URIString -- ^ The URL that was extracted- , ueExpanded :: URIString -- ^ The fully resolved URL (only for t.co links)- , ueDisplay :: Text -- ^ Not a URL but a string to display instead of the URL (only for t.co links)- } deriving (Show, Eq)+ URLEntity+ { ueURL :: URIString -- ^ The URL that was extracted+ , ueExpanded :: URIString -- ^ The fully resolved URL (only for t.co links)+ , ueDisplay :: Text -- ^ Not a URL but a string to display instead of the URL (only for t.co links)+ } deriving (Show, Eq) instance FromJSON URLEntity where- parseJSON (Object o) =- URLEntity <$> o .: "url"- <*> o .: "expanded_url"- <*> o .: "display_url"- parseJSON _ = mzero+ parseJSON (Object o) =+ URLEntity <$> o .: "url"+ <*> o .: "expanded_url"+ <*> o .: "display_url"+ parseJSON _ = mzero data MediaEntity =- MediaEntity- { meType :: Text- , meId :: StatusId- , meSizes :: HashMap Text MediaSize- , meMediaURL :: URIString- , meMediaURLHttps :: URIString- , meURL :: URLEntity- } deriving (Show, Eq)+ MediaEntity+ { meType :: Text+ , meId :: StatusId+ , meSizes :: HashMap Text MediaSize+ , meMediaURL :: URIString+ , meMediaURLHttps :: URIString+ , meURL :: URLEntity+ } deriving (Show, Eq) instance FromJSON MediaEntity where- parseJSON v@(Object o) =- MediaEntity <$> o .: "type"- <*> o .: "id"- <*> o .: "sizes"- <*> o .: "media_url"- <*> o .: "media_url_https"- <*> parseJSON v- parseJSON _ = mzero+ parseJSON v@(Object o) =+ MediaEntity <$> o .: "type"+ <*> o .: "id"+ <*> o .: "sizes"+ <*> o .: "media_url"+ <*> o .: "media_url_https"+ <*> parseJSON v+ parseJSON _ = mzero data MediaSize =- MediaSize- { msWidth :: Int- , msHeight :: Int- , msResize :: Text- } deriving (Show, Eq)+ MediaSize+ { msWidth :: Int+ , msHeight :: Int+ , msResize :: Text+ } deriving (Show, Eq) instance FromJSON MediaSize where- parseJSON (Object o) =- MediaSize <$> o .: "w"- <*> o .: "h"- <*> o .: "resize"- parseJSON _ = mzero+ parseJSON (Object o) =+ MediaSize <$> o .: "w"+ <*> o .: "h"+ <*> o .: "resize"+ parseJSON _ = mzero data Coordinates =- Coordinates- { coordinates :: [Double]- , coordinatesType :: Text- } deriving (Show, Eq)+ Coordinates+ { coordinates :: [Double]+ , coordinatesType :: Text+ } deriving (Show, Eq) instance FromJSON Coordinates where- parseJSON (Object o) =- Coordinates <$> o .: "coordinates"- <*> o .: "type"- parseJSON _ = mzero+ parseJSON (Object o) =+ Coordinates <$> o .: "coordinates"+ <*> o .: "type"+ parseJSON _ = mzero data Place =- Place- { placeAttributes :: HashMap Text Text- , placeBoundingBox :: BoundingBox- , placeCountry :: Text- , placeCountryCode :: Text- , placeFullName :: Text- , placeId :: Text- , placeName :: Text- , placeType :: Text- , placeUrl :: Text- } deriving (Show, Eq)+ Place+ { placeAttributes :: HashMap Text Text+ , placeBoundingBox :: BoundingBox+ , placeCountry :: Text+ , placeCountryCode :: Text+ , placeFullName :: Text+ , placeId :: Text+ , placeName :: Text+ , placeType :: Text+ , placeURL :: Text+ } deriving (Show, Eq) instance FromJSON Place where- parseJSON (Object o) =- Place <$> o .: "attributes"- <*> o .: "bounding_box"- <*> o .: "country"- <*> o .: "country_code"- <*> o .: "full_name"- <*> o .: "id"- <*> o .: "name"- <*> o .: "place_type"- <*> o .: "url"- parseJSON _ = mzero+ parseJSON (Object o) =+ Place <$> o .: "attributes"+ <*> o .: "bounding_box"+ <*> o .: "country"+ <*> o .: "country_code"+ <*> o .: "full_name"+ <*> o .: "id"+ <*> o .: "name"+ <*> o .: "place_type"+ <*> o .: "url"+ parseJSON _ = mzero data BoundingBox =- BoundingBox- { boundingBoxCoordinates :: [[[Double]]]- , boundingBoxType :: Text- } deriving (Show, Eq)+ BoundingBox+ { boundingBoxCoordinates :: [[[Double]]]+ , boundingBoxType :: Text+ } deriving (Show, Eq) instance FromJSON BoundingBox where- parseJSON (Object o) =- BoundingBox <$> o .: "coordinates"- <*> o .: "type"- parseJSON _ = mzero+ parseJSON (Object o) =+ BoundingBox <$> o .: "coordinates"+ <*> o .: "type"+ parseJSON _ = mzero -- | Entity handling. data Entities =- Entities- { enHashTags :: [Entity HashTagEntity]- , enUserMentions :: [Entity UserEntity]- , enURLs :: [Entity URLEntity]- , enMedia :: [Entity MediaEntity]- } deriving (Show, Eq)+ Entities+ { enHashTags :: [Entity HashTagEntity]+ , enUserMentions :: [Entity UserEntity]+ , enURLs :: [Entity URLEntity]+ , enMedia :: [Entity MediaEntity]+ } deriving (Show, Eq) instance FromJSON Entities where- parseJSON (Object o) =- Entities <$> o .:? "hashtags" .!= []- <*> o .:? "user_mentions" .!= []- <*> o .:? "urls" .!= []- <*> o .:? "media" .!= []- parseJSON _ = mzero+ parseJSON (Object o) =+ Entities <$> o .:? "hashtags" .!= []+ <*> o .:? "user_mentions" .!= []+ <*> o .:? "urls" .!= []+ <*> o .:? "media" .!= []+ parseJSON _ = mzero -- | The character positions the Entity was extracted from --@@ -485,13 +556,24 @@ type EntityIndices = [Int] data Entity a =- Entity- { entityBody :: a -- ^ The detail information of the specific entity types (HashTag, URL, User)- , entityIndices :: EntityIndices -- ^ The character positions the Entity was extracted from- } deriving (Show, Eq)+ Entity+ { entityBody :: a -- ^ The detail information of the specific entity types (HashTag, URL, User)+ , entityIndices :: EntityIndices -- ^ The character positions the Entity was extracted from+ } deriving (Show, Eq) instance FromJSON a => FromJSON (Entity a) where- parseJSON v@(Object o) =- Entity <$> parseJSON v- <*> o .: "indices"- parseJSON _ = mzero+ parseJSON v@(Object o) =+ Entity <$> parseJSON v+ <*> o .: "indices"+ parseJSON _ = mzero++data Contributor = Contributor+ { contributorId :: UserId+ , contributorScreenName :: Text+ } deriving (Show, Eq)++instance FromJSON Contributor where+ parseJSON (Object o) =+ Contributor <$> o .: "id"+ <*> o .: "screen_name"+ parseJSON _ = mzero
Web/Twitter/Types/Lens.hs view
@@ -1,55 +1,65 @@+{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE OverloadedStrings, DeriveDataTypeable, RankNTypes, CPP, FlexibleInstances #-} module Web.Twitter.Types.Lens- ( DateString- , UserId- , Friends- , URIString- , UserName- , StatusId- , LanguageCode- , StreamingAPI(..)- , Status- , SearchResult- , SearchStatus- , SearchMetadata- , RetweetedStatus- , DirectMessage- , EventTarget(..)- , Event- , Delete- , User- , List- , Entities- , EntityIndices- , Entity- , HashTagEntity- , UserEntity- , URLEntity- , MediaEntity- , MediaSize- , Coordinates- , Place- , BoundingBox+ ( TT.DateString+ , TT.UserId+ , TT.Friends+ , TT.URIString+ , TT.UserName+ , TT.StatusId+ , TT.LanguageCode+ , TT.StreamingAPI(..)+ , TT.Status+ , TT.SearchResult+ , TT.SearchStatus+ , TT.SearchMetadata+ , TT.RetweetedStatus+ , TT.DirectMessage+ , TT.EventTarget(..)+ , TT.Event+ , TT.Delete+ , TT.User+ , TT.List+ , TT.Entities+ , TT.EntityIndices+ , TT.Entity+ , TT.HashTagEntity+ , TT.UserEntity+ , TT.URLEntity+ , TT.MediaEntity+ , TT.MediaSize+ , TT.Coordinates+ , TT.Place+ , TT.BoundingBox + , statusContributors+ , statusCoordinates , statusCreatedAt- , statusId- , statusText- , statusSource- , statusTruncated+ , statusCurrentUserRetweet , statusEntities , statusExtendedEntities- , statusInReplyTo- , statusInReplyToUser- , statusFavorite- , statusRetweetCount- , statusRetweet- , statusUser- , statusPlace , statusFavoriteCount+ , statusFavorited+ , statusFilterLevel+ , statusId+ , statusInReplyToScreenName+ , statusInReplyToStatusId+ , statusInReplyToUserId , statusLang+ , statusPlace , statusPossiblySensitive- , statusCoordinates+ , statusScopes+ , statusRetweetCount+ , statusRetweeted+ , statusRetweetedStatus+ , statusSource+ , statusText+ , statusTruncated+ , statusUser+ , statusWithheldCopyright+ , statusWithheldInCountries+ , statusWithheldScope , searchResultStatuses , searchResultSearchMetadata@@ -63,7 +73,7 @@ , searchMetadataMaxId , searchMetadataSinceId- , searchMetadataRefreshUrl+ , searchMetadataRefreshURL , searchMetadataNextResults , searchMetadataCount , searchMetadataCompletedIn@@ -101,19 +111,46 @@ , delId , delUserId - , userId- , userName- , userScreenName+ , userContributorsEnabled+ , userCreatedAt+ , userDefaultProfile+ , userDefaultProfileImage , userDescription+ , userFavoritesCount+ , userFollowRequestSent+ , userFollowing+ , userFollowersCount+ , userFriendsCount+ , userGeoEnabled+ , userId+ , userIsTranslator+ , userLang+ , userListedCount , userLocation+ , userName+ , userNotifications+ , userProfileBackgroundColor+ , userProfileBackgroundImageURL+ , userProfileBackgroundImageURLHttps+ , userProfileBackgroundTile+ , userProfileBannerURL , userProfileImageURL- , userURL+ , userProfileImageURLHttps+ , userProfileLinkColor+ , userProfileSidebarBorderColor+ , userProfileSidebarFillColor+ , userProfileTextColor+ , userProfileUseBackgroundImage , userProtected- , userFollowers- , userFriends- , userTweets- , userLangCode- , userCreatedAt+ , userScreenName+ , userShowAllInlineMedia+ , userStatusesCount+ , userTimeZone+ , userURL+ , userUtcOffset+ , userVerified+ , userWithheldInCountries+ , userWithheldScope , listId , listName@@ -155,7 +192,7 @@ , placeId , placeName , placeType- , placeUrl+ , placeURL , boundingBoxCoordinates , boundingBoxType@@ -173,221 +210,61 @@ ) where -import Data.Functor+import Web.Twitter.Types.Lens.Types import qualified Web.Twitter.Types as TT-import Web.Twitter.Types- ( DateString- , UserId- , Friends- , URIString- , UserName- , StatusId- , LanguageCode- , StreamingAPI- , Status- , SearchResult- , SearchStatus- , SearchMetadata- , RetweetedStatus- , DirectMessage- , EventTarget- , Event- , Delete- , User- , List- , Entities- , EntityIndices- , Entity- , HashTagEntity- , UserEntity- , URLEntity- , MediaEntity- , MediaSize- , Coordinates- , Place- , BoundingBox- ) import Data.Text (Text)-import Data.HashMap.Strict (HashMap)--type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t-type SimpleLens s a = Lens s s a a--#define HASHSIGN #-#define SIMPLE_LENS(name, s, a) \-name :: SimpleLens (s) (a);\-name f record = (\newVal -> record { TT.name = newVal }) <$> (f (TT.name record));\-{-HASHSIGN INLINE name HASHSIGN-}--#define TYPECHANGE_LENS(name, s) \-name :: Lens ((s) a) ((s) b) (a) (b);\-name f record = (\newVal -> record { TT.name = newVal }) <$> (f (TT.name record))--SIMPLE_LENS(statusCreatedAt , Status, DateString )-SIMPLE_LENS(statusId , Status, StatusId )-SIMPLE_LENS(statusText , Status, Text )-SIMPLE_LENS(statusSource , Status, Text )-SIMPLE_LENS(statusTruncated , Status, Bool )-SIMPLE_LENS(statusEntities , Status, Maybe Entities )-SIMPLE_LENS(statusExtendedEntities , Status, Maybe Entities )-SIMPLE_LENS(statusInReplyTo , Status, Maybe StatusId )-SIMPLE_LENS(statusInReplyToUser , Status, Maybe UserId )-SIMPLE_LENS(statusFavorite , Status, Maybe Bool )-SIMPLE_LENS(statusRetweetCount , Status, Maybe Integer )-SIMPLE_LENS(statusRetweet , Status, Maybe Status )-SIMPLE_LENS(statusUser , Status, User )-SIMPLE_LENS(statusPlace , Status, Maybe Place )-SIMPLE_LENS(statusFavoriteCount , Status, Integer )-SIMPLE_LENS(statusLang , Status, Maybe Text )-SIMPLE_LENS(statusPossiblySensitive , Status, Maybe Bool )-SIMPLE_LENS(statusCoordinates , Status, Maybe Coordinates )--TYPECHANGE_LENS(searchResultStatuses , SearchResult )-SIMPLE_LENS(searchResultSearchMetadata, SearchResult body, SearchMetadata )--SIMPLE_LENS(searchStatusCreatedAt , SearchStatus, DateString )-SIMPLE_LENS(searchStatusId , SearchStatus, StatusId )-SIMPLE_LENS(searchStatusText , SearchStatus, Text )-SIMPLE_LENS(searchStatusSource , SearchStatus, Text )-SIMPLE_LENS(searchStatusUser , SearchStatus, User )-SIMPLE_LENS(searchStatusCoordinates , SearchStatus, Maybe Coordinates )--SIMPLE_LENS(searchMetadataMaxId , SearchMetadata, StatusId )-SIMPLE_LENS(searchMetadataSinceId , SearchMetadata, StatusId )-SIMPLE_LENS(searchMetadataRefreshUrl , SearchMetadata, URIString )-SIMPLE_LENS(searchMetadataNextResults , SearchMetadata, Maybe URIString )-SIMPLE_LENS(searchMetadataCount , SearchMetadata, Int )-SIMPLE_LENS(searchMetadataCompletedIn , SearchMetadata, Maybe Float )-SIMPLE_LENS(searchMetadataSinceIdStr , SearchMetadata, String )-SIMPLE_LENS(searchMetadataQuery , SearchMetadata, String )-SIMPLE_LENS(searchMetadataMaxIdStr , SearchMetadata, String )--SIMPLE_LENS(rsCreatedAt , RetweetedStatus, DateString )-SIMPLE_LENS(rsId , RetweetedStatus, StatusId )-SIMPLE_LENS(rsText , RetweetedStatus, Text )-SIMPLE_LENS(rsSource , RetweetedStatus, Text )-SIMPLE_LENS(rsTruncated , RetweetedStatus, Bool )-SIMPLE_LENS(rsEntities , RetweetedStatus, Maybe Entities )-SIMPLE_LENS(rsUser , RetweetedStatus, User )-SIMPLE_LENS(rsRetweetedStatus , RetweetedStatus, Status )-SIMPLE_LENS(rsCoordinates , RetweetedStatus, Maybe Coordinates )--SIMPLE_LENS(dmCreatedAt , DirectMessage, DateString )-SIMPLE_LENS(dmSenderScreenName , DirectMessage, Text )-SIMPLE_LENS(dmSender , DirectMessage, User )-SIMPLE_LENS(dmText , DirectMessage, Text )-SIMPLE_LENS(dmRecipientScreeName , DirectMessage, Text )-SIMPLE_LENS(dmId , DirectMessage, StatusId )-SIMPLE_LENS(dmRecipient , DirectMessage, User )-SIMPLE_LENS(dmRecipientId , DirectMessage, UserId )-SIMPLE_LENS(dmSenderId , DirectMessage, UserId )-SIMPLE_LENS(dmCoordinates , DirectMessage, Maybe Coordinates )--SIMPLE_LENS(evCreatedAt , Event, DateString )-SIMPLE_LENS(evTargetObject , Event, Maybe EventTarget )-SIMPLE_LENS(evEvent , Event, Text )-SIMPLE_LENS(evTarget , Event, EventTarget )-SIMPLE_LENS(evSource , Event, EventTarget )--SIMPLE_LENS(delId , Delete, StatusId )-SIMPLE_LENS(delUserId , Delete, UserId )--SIMPLE_LENS(userId , User, UserId )-SIMPLE_LENS(userName , User, UserName )-SIMPLE_LENS(userScreenName , User, Text )-SIMPLE_LENS(userDescription , User, Maybe Text )-SIMPLE_LENS(userLocation , User, Maybe Text )-SIMPLE_LENS(userProfileImageURL , User, Maybe URIString )-SIMPLE_LENS(userURL , User, Maybe URIString )-SIMPLE_LENS(userProtected , User, Maybe Bool )-SIMPLE_LENS(userFollowers , User, Maybe Int )-SIMPLE_LENS(userFriends , User, Maybe Int )-SIMPLE_LENS(userTweets , User, Maybe Int )-SIMPLE_LENS(userLangCode , User, Maybe LanguageCode )-SIMPLE_LENS(userCreatedAt , User, Maybe DateString )--SIMPLE_LENS(listId , List, Int )-SIMPLE_LENS(listName , List, Text )-SIMPLE_LENS(listFullName , List, Text )-SIMPLE_LENS(listMemberCount , List, Int )-SIMPLE_LENS(listSubscriberCount , List, Int )-SIMPLE_LENS(listMode , List, Text )-SIMPLE_LENS(listUser , List, User )--SIMPLE_LENS(hashTagText , HashTagEntity, Text )--SIMPLE_LENS(userEntityUserId , UserEntity, UserId )-SIMPLE_LENS(userEntityUserName , UserEntity, UserName )-SIMPLE_LENS(userEntityUserScreenName , UserEntity, Text )--SIMPLE_LENS(ueURL , URLEntity, URIString )-SIMPLE_LENS(ueExpanded , URLEntity, URIString )-SIMPLE_LENS(ueDisplay , URLEntity, Text )--SIMPLE_LENS(meType , MediaEntity, Text )-SIMPLE_LENS(meId , MediaEntity, StatusId )-SIMPLE_LENS(meSizes , MediaEntity, HashMap Text MediaSize )-SIMPLE_LENS(meMediaURL , MediaEntity, URIString )-SIMPLE_LENS(meMediaURLHttps , MediaEntity, URIString )-SIMPLE_LENS(meURL , MediaEntity, URLEntity )--SIMPLE_LENS(msWidth , MediaSize, Int )-SIMPLE_LENS(msHeight , MediaSize, Int )-SIMPLE_LENS(msResize , MediaSize, Text )--SIMPLE_LENS(coordinates , Coordinates, [Double] )-SIMPLE_LENS(coordinatesType , Coordinates, Text )--SIMPLE_LENS(placeAttributes , Place, HashMap Text Text )-SIMPLE_LENS(placeBoundingBox , Place, BoundingBox )-SIMPLE_LENS(placeCountry , Place, Text )-SIMPLE_LENS(placeCountryCode , Place, Text )-SIMPLE_LENS(placeFullName , Place, Text )-SIMPLE_LENS(placeId , Place, Text )-SIMPLE_LENS(placeName , Place, Text )-SIMPLE_LENS(placeType , Place, Text )-SIMPLE_LENS(placeUrl , Place, Text )--SIMPLE_LENS(boundingBoxCoordinates , BoundingBox, [[[Double]]] )-SIMPLE_LENS(boundingBoxType , BoundingBox, Text )--SIMPLE_LENS(enHashTags , Entities, [Entity HashTagEntity] )-SIMPLE_LENS(enUserMentions , Entities, [Entity UserEntity] )-SIMPLE_LENS(enURLs , Entities, [Entity URLEntity] )-SIMPLE_LENS(enMedia , Entities, [Entity MediaEntity] )+import Web.Twitter.Types.Lens.TH -TYPECHANGE_LENS(entityBody , Entity )-SIMPLE_LENS(entityIndices , Entity a, EntityIndices )+makeLenses ''TT.Status+makeLenses ''TT.SearchResult+makeLenses ''TT.SearchStatus+makeLenses ''TT.SearchMetadata+makeLenses ''TT.RetweetedStatus+makeLenses ''TT.DirectMessage+makeLenses ''TT.Event+makeLenses ''TT.Delete+makeLenses ''TT.User+makeLenses ''TT.List+makeLenses ''TT.HashTagEntity+makeLenses ''TT.UserEntity+makeLenses ''TT.URLEntity+makeLenses ''TT.MediaEntity+makeLenses ''TT.MediaSize+makeLenses ''TT.Coordinates+makeLenses ''TT.Place+makeLenses ''TT.BoundingBox+makeLenses ''TT.Entities+makeLenses ''TT.Entity class AsStatus s where- status_id :: SimpleLens s StatusId- text :: SimpleLens s Text- user :: SimpleLens s User- created_at :: SimpleLens s DateString- geolocation :: SimpleLens s (Maybe Coordinates)+ status_id :: Lens' s TT.StatusId+ text :: Lens' s Text+ user :: Lens' s TT.User+ created_at :: Lens' s TT.DateString+ geolocation :: Lens' s (Maybe TT.Coordinates) -instance AsStatus Status where+instance AsStatus TT.Status where status_id = statusId text = statusText user = statusUser created_at = statusCreatedAt geolocation = statusCoordinates -instance AsStatus SearchStatus where+instance AsStatus TT.SearchStatus where status_id = searchStatusId text = searchStatusText user = searchStatusUser created_at = searchStatusCreatedAt geolocation = searchStatusCoordinates -instance AsStatus RetweetedStatus where+instance AsStatus TT.RetweetedStatus where status_id = rsId text = rsText user = rsUser created_at = rsCreatedAt geolocation = rsCoordinates -instance AsStatus DirectMessage where+instance AsStatus TT.DirectMessage where status_id = dmId text = dmText user = dmSender@@ -395,21 +272,21 @@ geolocation = dmCoordinates class AsUser u where- user_id :: SimpleLens u UserId- name :: SimpleLens u UserName- screen_name :: SimpleLens u Text+ user_id :: Lens' u TT.UserId+ name :: Lens' u TT.UserName+ screen_name :: Lens' u Text -instance AsUser User where+instance AsUser TT.User where user_id = userId name = userName screen_name = userScreenName -instance AsUser UserEntity where+instance AsUser TT.UserEntity where user_id = userEntityUserId name = userEntityUserName screen_name = userEntityUserScreenName -instance AsUser (Entity UserEntity) where+instance AsUser (TT.Entity TT.UserEntity) where user_id = entityBody.userEntityUserId name = entityBody.userEntityUserName screen_name = entityBody.userEntityUserScreenName
+ Web/Twitter/Types/Lens/TH.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE CPP #-}++module Web.Twitter.Types.Lens.TH+ where++import Language.Haskell.TH+import Language.Haskell.TH.Syntax+import Web.Twitter.Types.Lens.Types++makeLenses :: Name -> Q [Dec]+makeLenses typename = do+ typeinfo <- reify typename+ case typeinfo of+ TyConI (DataD _cxt _name tyVarBndr [RecC _dataConName fields] _names) ->+ makeFieldLenses typename tyVarBndr fields+ _ -> error $ "unknown type info: reify " ++ show typename++makeFieldLenses :: Name -> [TyVarBndr] -> [VarStrictType] -> Q [Dec]+makeFieldLenses tyConName tyVarBndr fields = do+ fieldsDec <- mapM (eachField tyConName tyVarBndr) fields+ return $ concat fieldsDec++eachField :: Name -> [TyVarBndr] -> (Name, Strict, Type) -> Q [Dec]+eachField tyConName tyVarBndr (fieldName, _, fieldType) = do+ let funN = mkName (nameBase fieldName)+ sigdef <- eachFieldSigD funN tyConName tyVarBndr fieldType+ f <- newName "f"+ record <- newName "record"+ newVal <- newName "newVal"+ recUpdVal <- varE newVal+ let expr = [|fmap|]+ `appE` (lamE [varP newVal] (recUpdE (varE record) [return (fieldName, recUpdVal)]))+ `appE` (varE f `appE` (varE fieldName `appE` varE record))+ bind <- funD funN [clause [varP f, varP record] (normalB expr) []]+#if MIN_VERSION_template_haskell(2,8,0)+ -- GHC 7.6+ pragD <- pragInlD funN Inline FunLike AllPhases+ return [sigdef, bind, pragD]+#elif MIN_VERSION_template_haskell(2,6,0)+ -- GHC 7.4+ pragD <- pragInlD funN (inlineSpecNoPhase True False)+ return [sigdef, bind, pragD]+#else+ return [sigdef, bind]+#endif++eachFieldSigD :: Name -> Name -> [TyVarBndr] -> Type -> DecQ+eachFieldSigD funN tyConName [_] (VarT _fieldTypeVal) = do+ a <- newName "a"+ b <- newName "b"+ let typ = forallT [PlainTV a, PlainTV b] (return []) (conT ''Lens `appT` (conT tyConName `appT` varT a) `appT` (conT tyConName `appT` varT b) `appT` varT a `appT` varT b)+ sigD funN typ+eachFieldSigD funN tyConName [PlainTV a] fieldType = do+ let typ = forallT [PlainTV a] (return []) (conT ''Lens' `appT` (conT tyConName `appT` varT a) `appT` return fieldType)+ sigD funN typ+eachFieldSigD funN tyConName [] fieldType = do+ sigD funN (conT ''Lens' `appT` conT tyConName `appT` return fieldType)+eachFieldSigD funN tyConName tyVarBndr fieldType =+ error $ "Unknown TH : " ++ show funN ++ " " ++ show tyConName ++ " " ++ show tyVarBndr ++ " " ++ show fieldType
+ Web/Twitter/Types/Lens/Types.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE RankNTypes #-}++module Web.Twitter.Types.Lens.Types+ ( Lens+ , Lens'+ ) where++-- | A type alias of the lens.+-- It is the same definition as the lens which introduced in+-- <http://hackage.haskell.org/package/lens-4.3.3/docs/Control-Lens-Type.html#t:Lens>+type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t++-- | Same as Lens' <http://hackage.haskell.org/package/lens-4.3.3/docs/Control-Lens-Type.html#t:Lens-39->+type Lens' s a = Lens s s a a
tests/Fixtures.hs view
@@ -1,29 +1,39 @@ {-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE CPP #-} module Fixtures where +import Language.Haskell.TH import Data.Aeson import Data.Attoparsec.ByteString-import qualified Data.Text as T-import qualified Data.Text.Encoding as T-import Data.Maybe (fromJust)-import Text.Shakespeare.Text--fj :: T.Text -> Value-fj = fromJust . maybeResult . parse json . T.encodeUtf8+import qualified Data.ByteString as S+import Data.Maybe+import System.Directory+import System.FilePath+import System.IO.Unsafe (unsafePerformIO)+import Control.Applicative -errorMsgJson :: Value-errorMsgJson = fj [st|{"request":"\/1\/statuses\/user_timeline.json","error":"Not authorized"}|]+parseJSONValue :: S.ByteString -> Value+parseJSONValue = fromJust . maybeResult . parse json -statusJson :: Value-statusJson = fj [st|{"created_at":"Sat Sep 10 22:23:38 +0000 2011","id":112652479837110273,"id_str":"112652479837110273","text":"@twitter meets @seepicturely at #tcdisrupt cc.@boscomonkey @episod http:\/\/t.co\/6J2EgYM","source":"\u003ca href=\"http:\/\/instagr.am\" rel=\"nofollow\"\u003eInstagram\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":783214,"in_reply_to_user_id_str":"783214","in_reply_to_screen_name":"twitter","user":{"id":299862462,"id_str":"299862462","name":"Eoin McMillan ","screen_name":"imeoin","location":"Twitter","description":"Eoin's photography account. See @mceoin for tweets.","url":"http:\/\/www.eoin.me","protected":false,"followers_count":6,"friends_count":0,"listed_count":0,"created_at":"Mon May 16 20:07:59 +0000 2011","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":277,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"131516","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme14\/bg.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme14\/bg.gif","profile_background_tile":true,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1380912173\/Screen_shot_2011-06-03_at_7.35.36_PM_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1380912173\/Screen_shot_2011-06-03_at_7.35.36_PM_normal.png","profile_link_color":"009999","profile_sidebar_border_color":"EEEEEE","profile_sidebar_fill_color":"EFEFEF","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":false,"default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"favorited":false,"retweeted":false,"possibly_sensitive":false}|]+fixturePath :: String+fixturePath = takeDirectory __FILE__ </> "fixtures" -statusEntityJson :: Value-statusEntityJson = fj [st|{"created_at":"Sat Sep 10 22:23:38 +0000 2011","id":112652479837110273,"id_str":"112652479837110273","text":"@twitter meets @seepicturely at #tcdisrupt cc.@boscomonkey @episod http:\/\/t.co\/6J2EgYM","source":"\u003ca href=\"http:\/\/instagr.am\" rel=\"nofollow\"\u003eInstagram\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":783214,"in_reply_to_user_id_str":"783214","in_reply_to_screen_name":"twitter","user":{"id":299862462,"id_str":"299862462","name":"Eoin McMillan ","screen_name":"imeoin","location":"Twitter","description":"Eoin's photography account. See @mceoin for tweets.","url":"http:\/\/www.eoin.me","protected":false,"followers_count":6,"friends_count":0,"listed_count":0,"created_at":"Mon May 16 20:07:59 +0000 2011","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":277,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"131516","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme14\/bg.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme14\/bg.gif","profile_background_tile":true,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1380912173\/Screen_shot_2011-06-03_at_7.35.36_PM_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1380912173\/Screen_shot_2011-06-03_at_7.35.36_PM_normal.png","profile_link_color":"009999","profile_sidebar_border_color":"EEEEEE","profile_sidebar_fill_color":"EFEFEF","profile_text_color":"333333","profile_use_background_image":true,"show_all_inline_media":false,"default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"entities":{"hashtags":[{"text":"tcdisrupt","indices":[32,42]}],"urls":[{"url":"http:\/\/t.co\/6J2EgYM","expanded_url":"http:\/\/instagr.am\/p\/MuW67\/","display_url":"instagr.am\/p\/MuW67\/","indices":[67,86]}],"user_mentions":[{"screen_name":"twitter","name":"Twitter","id":783214,"id_str":"783214","indices":[0,8]},{"screen_name":"boscomonkey","name":"Bosco So","id":14792670,"id_str":"14792670","indices":[46,58]},{"screen_name":"episod","name":"Taylor Singletary","id":819797,"id_str":"819797","indices":[59,66]}]},"favorited":false,"retweeted":false,"possibly_sensitive":false}|]+loadFixture :: (S.ByteString -> a) -> String -> IO a+loadFixture conv filename = conv <$> S.readFile (fixturePath </> filename) -mediaEntityJson :: Value-mediaEntityJson = fj [st|{"created_at":"Wed Sep 14 20:58:04 +0000 2011","id":114080493036773378,"id_str":"114080493036773378","text":"Hello America! http:\/\/t.co\/rJC5Pxsu","source":"web","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":373487136,"id_str":"373487136","name":"Y U No @rno?","screen_name":"yunorno","location":"Paris, France","url":"http:\/\/twitter.com\/rno","description":"Oui oui!","protected":false,"followers_count":32,"friends_count":3,"listed_count":2,"created_at":"Wed Sep 14 17:24:54 +0000 2011","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":27,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1542800106\/oui_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1542800106\/oui_normal.png","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":true,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":4,"entities":{"hashtags":[],"urls":[],"user_mentions":[],"media":[{"id":114080493040967680,"id_str":"114080493040967680","indices":[15,35],"media_url":"http:\/\/pbs.twimg.com\/media\/AZVLmp-CIAAbkyy.jpg","media_url_https":"https:\/\/pbs.twimg.com\/media\/AZVLmp-CIAAbkyy.jpg","url":"http:\/\/t.co\/rJC5Pxsu","display_url":"pic.twitter.com\/rJC5Pxsu","expanded_url":"http:\/\/twitter.com\/yunorno\/status\/114080493036773378\/photo\/1","type":"photo","sizes":{"large":{"w":226,"h":238,"resize":"fit"},"thumb":{"w":150,"h":150,"resize":"crop"},"medium":{"w":226,"h":238,"resize":"fit"},"small":{"w":226,"h":238,"resize":"fit"}}}]},"favorited":false,"retweeted":false,"possibly_sensitive":false}|]+fixture :: (S.ByteString -> a) -> String -> a+fixture conv = unsafePerformIO . loadFixture conv -mediaExtendedEntityJson :: Value-mediaExtendedEntityJson = fj [st|{"in_reply_to_status_id":null,"id_str":"479666034073296896","truncated":false,"possibly_sensitive":false,"in_reply_to_screen_name":null,"extended_entities":{"media":[{"id_str":"479665892922376192","expanded_url":"http://twitter.com/thimura_test/status/479666034073296896/photo/1","url":"http://t.co/qOjPwmgLKO","media_url_https":"https://pbs.twimg.com/media/BqgdlpaCQAA5OSu.jpg","indices":[36,58],"id":479665892922376192,"media_url":"http://pbs.twimg.com/media/BqgdlpaCQAA5OSu.jpg","type":"photo","sizes":{"small":{"w":340,"resize":"fit","h":604},"large":{"w":576,"resize":"fit","h":1024},"medium":{"w":576,"resize":"fit","h":1024},"thumb":{"w":150,"resize":"crop","h":150}},"display_url":"pic.twitter.com/qOjPwmgLKO"},{"id_str":"479665897150234624","expanded_url":"http://twitter.com/thimura_test/status/479666034073296896/photo/1","url":"http://t.co/qOjPwmgLKO","media_url_https":"https://pbs.twimg.com/media/Bqgdl5KCQAA9g9V.jpg","indices":[36,58],"id":479665897150234624,"media_url":"http://pbs.twimg.com/media/Bqgdl5KCQAA9g9V.jpg","type":"photo","sizes":{"small":{"w":339,"resize":"fit","h":191},"large":{"w":1024,"resize":"fit","h":576},"medium":{"w":599,"resize":"fit","h":337},"thumb":{"w":150,"resize":"crop","h":150}},"display_url":"pic.twitter.com/qOjPwmgLKO"},{"id_str":"479665901545852929","expanded_url":"http://twitter.com/thimura_test/status/479666034073296896/photo/1","url":"http://t.co/qOjPwmgLKO","media_url_https":"https://pbs.twimg.com/media/BqgdmJiCEAEp0EI.jpg","indices":[36,58],"id":479665901545852929,"media_url":"http://pbs.twimg.com/media/BqgdmJiCEAEp0EI.jpg","type":"photo","sizes":{"small":{"w":339,"resize":"fit","h":225},"large":{"w":1024,"resize":"fit","h":678},"medium":{"w":599,"resize":"fit","h":397},"thumb":{"w":150,"resize":"crop","h":150}},"display_url":"pic.twitter.com/qOjPwmgLKO"},{"id_str":"479665905375256576","expanded_url":"http://twitter.com/thimura_test/status/479666034073296896/photo/1","url":"http://t.co/qOjPwmgLKO","media_url_https":"https://pbs.twimg.com/media/BqgdmXzCIAAa2lU.jpg","indices":[36,58],"id":479665905375256576,"media_url":"http://pbs.twimg.com/media/BqgdmXzCIAAa2lU.jpg","type":"photo","sizes":{"small":{"w":339,"resize":"fit","h":225},"large":{"w":1024,"resize":"fit","h":678},"medium":{"w":599,"resize":"fit","h":397},"thumb":{"w":150,"resize":"crop","h":150}},"display_url":"pic.twitter.com/qOjPwmgLKO"}]},"entities":{"symbols":[],"urls":[],"media":[{"id_str":"479665892922376192","expanded_url":"http://twitter.com/thimura_test/status/479666034073296896/photo/1","url":"http://t.co/qOjPwmgLKO","media_url_https":"https://pbs.twimg.com/media/BqgdlpaCQAA5OSu.jpg","indices":[36,58],"id":479665892922376192,"media_url":"http://pbs.twimg.com/media/BqgdlpaCQAA5OSu.jpg","type":"photo","sizes":{"small":{"w":340,"resize":"fit","h":604},"large":{"w":576,"resize":"fit","h":1024},"medium":{"w":576,"resize":"fit","h":1024},"thumb":{"w":150,"resize":"crop","h":150}},"display_url":"pic.twitter.com/qOjPwmgLKO"}],"user_mentions":[],"hashtags":[{"text":"testnyan","indices":[26,35]}]},"text":"multiple image tweet test #testnyan http://t.co/qOjPwmgLKO","in_reply_to_user_id_str":null,"favorited":false,"coordinates":null,"retweeted":false,"user":{"screen_name":"thimura_test","is_translation_enabled":false,"default_profile":true,"profile_image_url":"http://abs.twimg.com/sticky/default_profile_images/default_profile_6_normal.png","default_profile_image":true,"id_str":"2418883074","profile_background_image_url_https":"https://abs.twimg.com/images/themes/theme1/bg.png","protected":false,"location":"","entities":{"description":{"urls":[]}},"profile_background_color":"C0DEED","utc_offset":null,"url":null,"profile_text_color":"333333","profile_image_url_https":"https://abs.twimg.com/sticky/default_profile_images/default_profile_6_normal.png","verified":false,"statuses_count":5,"profile_background_tile":false,"following":false,"lang":"ja","follow_request_sent":false,"profile_sidebar_fill_color":"DDEEF6","time_zone":null,"name":"thimura test","profile_sidebar_border_color":"C0DEED","geo_enabled":false,"listed_count":0,"contributors_enabled":false,"created_at":"Sun Mar 30 11:47:17 +0000 2014","id":2418883074,"friends_count":2,"is_translator":false,"favourites_count":0,"notifications":false,"profile_background_image_url":"http://abs.twimg.com/images/themes/theme1/bg.png","profile_use_background_image":true,"description":"","profile_link_color":"0084B4","followers_count":2},"lang":"et","retweet_count":0,"in_reply_to_user_id":null,"created_at":"Thu Jun 19 16:44:28 +0000 2014","source":"\u003ca href=\"https://twitter.com/thimura\" rel=\"nofollow\"\u003e二階堂真紅\u003c/a\u003e","geo":null,"id":479666034073296896,"in_reply_to_status_id_str":null,"favorite_count":0,"contributors":null,"place":null}|]+loadFixturesTH :: Name -> Q [Dec]+loadFixturesTH convFn = do+ files <- runIO $ filter (\fn -> takeExtension fn == ".json") <$> getDirectoryContents fixturePath+ concat <$> mapM genEachDefs files+ where+ genEachDefs filename = do+ let funN = mkName $ "fixture_" ++ dropExtension filename+ sigdef <- sigD funN (conT ''Value)+ bind <- valD (varP funN) (normalB [|fixture $(varE convFn) $(litE (stringL filename))|]) []+ return [ sigdef, bind ]
tests/TypesTest.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE OverloadedStrings #-} module Main where@@ -8,7 +8,6 @@ import Test.Framework.TH.Prime import Test.Framework.Providers.HUnit import Test.HUnit-import Text.Shakespeare.Text import Data.Aeson hiding (Error) import Data.Aeson.Types (parseEither)@@ -16,6 +15,7 @@ import Data.Maybe import Fixtures+loadFixturesTH 'parseJSONValue main :: IO () main = $(defaultMainGenerator)@@ -25,57 +25,185 @@ -> (a -> Assertion) -> Assertion withJSON js f = either assertFailure id $ do- o <- parseEither parseJSON js- return $ f o+ o <- parseEither parseJSON js+ return $ f o case_parseStatus :: Assertion-case_parseStatus = withJSON statusJson $ \obj -> do- statusId obj @?= 112652479837110273- statusRetweetCount obj @?= Just 0- (userScreenName . statusUser) obj @?= "imeoin"- statusEntities obj @?= Nothing+case_parseStatus = withJSON fixture_status01 $ \obj -> do+ statusCreatedAt obj @?= "Sat Sep 10 22:23:38 +0000 2011"+ statusId obj @?= 112652479837110273+ statusText obj @?= "@twitter meets @seepicturely at #tcdisrupt cc.@boscomonkey @episod http://t.co/6J2EgYM"+ statusSource obj @?= "<a href=\"http://instagr.am\" rel=\"nofollow\">Instagram</a>"+ statusTruncated obj @?= False+ statusEntities obj @?= Nothing+ statusExtendedEntities obj @?= Nothing+ statusInReplyToStatusId obj @?= Nothing+ statusInReplyToUserId obj @?= Just 783214+ statusFavorited obj @?= Just False+ statusRetweetCount obj @?= 0+ (userScreenName . statusUser) obj @?= "imeoin"+ statusRetweetedStatus obj @?= Nothing+ statusPlace obj @?= Nothing+ statusFavoriteCount obj @?= 0+ statusLang obj @?= Nothing+ statusPossiblySensitive obj @?= Just False+ statusCoordinates obj @?= Nothing +case_parseStatusWithPhoto :: Assertion+case_parseStatusWithPhoto = withJSON fixture_status_thimura_with_photo $ \obj -> do+ statusId obj @?= 491143410770657280+ statusText obj @?= "近所の海です http://t.co/FjSOU8dDoD"+ statusTruncated obj @?= False++ let ent = fromJust $ statusEntities obj+ enHashTags ent @?= []+ enUserMentions ent @?= []+ enURLs ent @?= []+ length (enMedia ent) @?= 1+ map (meMediaURLHttps . entityBody) (enMedia ent) @?= ["https://pbs.twimg.com/media/BtDkUVaCQAIpWBU.jpg"]++ let exent = fromJust $ statusExtendedEntities obj+ enHashTags exent @?= []+ enUserMentions exent @?= []+ enURLs exent @?= []+ length (enMedia ent) @?= 1++ statusInReplyToStatusId obj @?= Nothing+ statusInReplyToUserId obj @?= Nothing+ statusFavorited obj @?= Just False+ statusRetweetCount obj @?= 4+ (userScreenName . statusUser) obj @?= "thimura"+ statusRetweetedStatus obj @?= Nothing+ statusPlace obj @?= Nothing+ statusFavoriteCount obj @?= 9+ statusLang obj @?= Just "ja"+ statusPossiblySensitive obj @?= Just False+ statusCoordinates obj @?= Nothing+ case_parseStatusIncludeEntities :: Assertion-case_parseStatusIncludeEntities = withJSON statusEntityJson $ \obj -> do- statusId obj @?= 112652479837110273- statusRetweetCount obj @?= Just 0- (userScreenName . statusUser) obj @?= "imeoin"- let ent = fromMaybe (Entities [] [] [] []) $ statusEntities obj- (map entityIndices . enHashTags) ent @?= [[32,42]]- (hashTagText . entityBody . head . enHashTags) ent @?= "tcdisrupt"+case_parseStatusIncludeEntities = withJSON fixture_status_with_entity $ \obj -> do+ statusId obj @?= 112652479837110273+ statusRetweetCount obj @?= 0+ (userScreenName . statusUser) obj @?= "imeoin"+ let ent = fromMaybe (Entities [] [] [] []) $ statusEntities obj+ (map entityIndices . enHashTags) ent @?= [[32,42]]+ (hashTagText . entityBody . head . enHashTags) ent @?= "tcdisrupt" +case_parseSearchStatusMetadata :: Assertion+case_parseSearchStatusMetadata = withJSON fixture_search_haskell $ \obj -> do+ let status = (searchResultStatuses obj) :: [Status]+ length status @?= 1++ let metadata = searchResultSearchMetadata obj+ searchMetadataMaxId metadata @?= 495597397733433345+ searchMetadataSinceId metadata @?= 0+ searchMetadataRefreshURL metadata @?= "?since_id=495597397733433345&q=haskell&include_entities=1"+ searchMetadataNextResults metadata @?= Just "?max_id=495594369802440705&q=haskell&include_entities=1"+ searchMetadataCount metadata @?= 1+ searchMetadataCompletedIn metadata @?= Just 0.043+ searchMetadataSinceIdStr metadata @?= "0"+ searchMetadataQuery metadata @?= "haskell"+ searchMetadataMaxIdStr metadata @?= "495597397733433345"++case_parseSearchStatusBodyStatus :: Assertion+case_parseSearchStatusBodyStatus = withJSON fixture_search_haskell $ \obj -> do+ let status = (searchResultStatuses obj) :: [Status]+ length status @?= 1+ statusText (head status) @?= "haskell"++case_parseSearchStatusBodySearchStatus :: Assertion+case_parseSearchStatusBodySearchStatus = withJSON fixture_search_haskell $ \obj -> do+ let status = (searchResultStatuses obj) :: [SearchStatus]+ length status @?= 1+ searchStatusText (head status) @?= "haskell"++case_parseDirectMessage :: Assertion+case_parseDirectMessage = withJSON fixture_direct_message_thimura $ \obj -> do+ dmCreatedAt obj @?= "Sat Aug 02 16:10:04 +0000 2014"+ dmSenderScreenName obj @?= "thimura_shinku"+ (userScreenName . dmSender) obj @?= "thimura_shinku"+ dmText obj @?= "おまえの明日が、今日よりもずっと、楽しい事で溢れているようにと、祈っているよ"+ dmRecipientScreeName obj @?= "thimura"+ dmId obj @?= 495602442466123776+ (userScreenName . dmRecipient) obj @?= "thimura"+ dmRecipientId obj @?= 69179963+ dmSenderId obj @?= 2566877347+ dmCoordinates obj @?= Nothing++case_parseEventFavorite :: Assertion+case_parseEventFavorite = withJSON fixture_event_favorite_thimura $ \obj -> do+ evCreatedAt obj @?= "Sat Aug 02 16:32:01 +0000 2014"+ evEvent obj @?= "favorite"+ let Just (ETStatus targetObj) = evTargetObject obj+ statusId targetObj @?= 495597326736449536+ statusText targetObj @?= "haskell"++ let ETUser targetUser = evTarget obj+ userScreenName targetUser @?= "thimura"++ let ETUser sourceUser = evSource obj+ userScreenName sourceUser @?= "thimura_shinku"++case_parseEventUnfavorite :: Assertion+case_parseEventUnfavorite = withJSON fixture_event_unfavorite_thimura $ \obj -> do+ evCreatedAt obj @?= "Sat Aug 02 16:32:10 +0000 2014"+ evEvent obj @?= "unfavorite"+ let Just (ETStatus targetObj) = evTargetObject obj+ statusId targetObj @?= 495597326736449536+ statusText targetObj @?= "haskell"++ let ETUser targetUser = evTarget obj+ userScreenName targetUser @?= "thimura"++ let ETUser sourceUser = evSource obj+ userScreenName sourceUser @?= "thimura_shinku"++case_parseDelete :: Assertion+case_parseDelete = withJSON fixture_delete $ \obj -> do+ delId obj @?= 495607981833064448+ delUserId obj @?= 2566877347+ case_parseErrorMsg :: Assertion case_parseErrorMsg =- case parseStatus errorMsgJson of- Left str -> "Not authorized" @=? str- Right _ -> assertFailure "errorMsgJson should be parsed as an error."+ case parseStatus fixture_error_not_authorized of+ Left str -> "Not authorized" @=? str+ Right _ -> assertFailure "errorMsgJson should be parsed as an error." where parseStatus :: Value -> Either String Status parseStatus = parseEither parseJSON case_parseMediaEntity :: Assertion-case_parseMediaEntity = withJSON mediaEntityJson $ \obj -> do- let entities = statusEntities obj- assert $ isJust entities- let Just ent = entities- media = enMedia ent- length media @?= 1- let me = entityBody $ head media- ueURL (meURL me) @?= "http://t.co/rJC5Pxsu"- meMediaURLHttps me @?= "https://pbs.twimg.com/media/AZVLmp-CIAAbkyy.jpg"- let sizes = meSizes me- assert $ M.member "thumb" sizes- assert $ M.member "large" sizes+case_parseMediaEntity = withJSON fixture_media_entity $ \obj -> do+ let entities = statusEntities obj+ assert $ isJust entities+ let Just ent = entities+ media = enMedia ent+ length media @?= 1+ let me = entityBody $ head media+ meType me @?= "photo"+ meId me @?= 114080493040967680+ let sizes = meSizes me+ assert $ M.member "thumb" sizes+ assert $ M.member "large" sizes + let Just mediaSize = M.lookup "large" sizes++ msWidth mediaSize @?= 226+ msHeight mediaSize @?= 238+ msResize mediaSize @?= "fit"++ ueURL (meURL me) @?= "http://t.co/rJC5Pxsu"+ meMediaURLHttps me @?= "https://pbs.twimg.com/media/AZVLmp-CIAAbkyy.jpg"+ case_parseEmptyEntity :: Assertion-case_parseEmptyEntity = withJSON (fj [st|{}|]) $ \entity -> do+case_parseEmptyEntity = withJSON (parseJSONValue "{}") $ \entity -> do length (enHashTags entity) @?= 0 length (enUserMentions entity) @?= 0 length (enURLs entity) @?= 0 length (enMedia entity) @?= 0 case_parseEntityHashTag :: Assertion-case_parseEntityHashTag = withJSON (fj [st|{"symbols":[],"urls":[{"indices":[32,52], "url":"http://t.co/IOwBrTZR", "display_url":"youtube.com/watch?v=oHg5SJ\u2026", "expanded_url":"http://www.youtube.com/watch?v=oHg5SJYRHA0"}],"user_mentions":[{"name":"Twitter API", "indices":[4,15], "screen_name":"twitterapi", "id":6253282, "id_str":"6253282"}],"hashtags":[{"indices":[32,36],"text":"lol"}]}|]) $ \entity -> do+case_parseEntityHashTag = withJSON fixture_entity01 $ \entity -> do length (enHashTags entity) @?= 1 length (enUserMentions entity) @?= 1 length (enURLs entity) @?= 1@@ -95,7 +223,7 @@ hashtag @?= "lol" case_parseExtendedEntities :: Assertion-case_parseExtendedEntities = withJSON mediaExtendedEntityJson $ \obj -> do+case_parseExtendedEntities = withJSON fixture_media_extended_entity $ \obj -> do let entities = statusExtendedEntities obj assert $ isJust entities let Just ent = entities@@ -104,3 +232,30 @@ let me = entityBody $ head media ueURL (meURL me) @?= "http://t.co/qOjPwmgLKO" meMediaURL me @?= "http://pbs.twimg.com/media/BqgdlpaCQAA5OSu.jpg"++case_parseUser :: Assertion+case_parseUser = withJSON fixture_user_thimura $ \obj -> do+ userId obj @?= 69179963+ userName obj @?= "ちむら"+ userScreenName obj @?= "thimura"+ userDescription obj @?= Just "真紅かわいい"+ userLocation obj @?= Just "State# Irotoridori.No.World"+ userProfileImageURL obj @?= Just "http://pbs.twimg.com/profile_images/414044387346116609/VNMfLpY7_normal.png"+ userURL obj @?= Just "http://t.co/TFUAsAffX0"+ userProtected obj @?= False+ userFollowersCount obj @?= 754+ userFriendsCount obj @?= 780+ userStatusesCount obj @?= 24709+ userLang obj @?= "en"+ userCreatedAt obj @?= "Thu Aug 27 02:48:06 +0000 2009"+ userFavoritesCount obj @?= 17313++case_parseList :: Assertion+case_parseList = withJSON fixture_list_thimura_haskell $ \obj -> do+ listId obj @?= 20849097+ listName obj @?= "haskell"+ listFullName obj @?= "@thimura/haskell"+ listMemberCount obj @?= 50+ listSubscriberCount obj @?= 1+ listMode obj @?= "public"+ (userScreenName . listUser) obj @?= "thimura"
twitter-types.cabal view
@@ -1,12 +1,12 @@ name: twitter-types-version: 0.3.20140801+version: 0.4.20140809 license: BSD3 license-file: LICENSE author: Takahiro HIMURA maintainer: Takahiro HIMURA <taka@himura.jp> synopsis: Twitter JSON parser and types description: This package uses enumerator package for access Twitter API.-category: Web, Enumerator+category: Web stability: Experimental cabal-version: >= 1.8 build-type: Simple@@ -29,11 +29,17 @@ , aeson >= 0.3.2.2 , text , unordered-containers+ , template-haskell exposed-modules: Web.Twitter.Types Web.Twitter.Types.Lens+ -- for documentation+ Web.Twitter.Types.Lens.Types + other-modules:+ Web.Twitter.Types.Lens.TH+ test-suite tests type: exitcode-stdio-1.0 hs-source-dirs: tests, .@@ -45,12 +51,14 @@ , test-framework-th-prime , test-framework-hunit , HUnit- , shakespeare >= 2.0 , http-types , aeson , attoparsec+ , bytestring , text , unordered-containers+ , filepath+ , directory other-modules: Fixtures