packages feed

scuttlebutt-types 0.2.0 → 0.3.0

raw patch · 5 files changed

+102/−12 lines, 5 filesdep +vectorPVP ok

version bump matches the API change (PVP)

Dependencies added: vector

API changes (from Hackage documentation)

- Ssb.Types.Message: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Ssb.Types.Message.Message a)
+ Ssb.Types.Message: Branch :: [MessageLink] -> Branch
+ Ssb.Types.Message: Mentions :: [Mention] -> Mentions
+ Ssb.Types.Message: [description] :: About -> Maybe Text
+ Ssb.Types.Message: [fromBranch] :: Branch -> [MessageLink]
+ Ssb.Types.Message: [fromMentions] :: Mentions -> [Mention]
+ Ssb.Types.Message: [mentionName] :: Mention -> Maybe Text
+ Ssb.Types.Message: contentType :: Message AnyContent -> Text
+ Ssb.Types.Message: instance Data.Aeson.Types.FromJSON.FromJSON Ssb.Types.Message.Branch
+ Ssb.Types.Message: instance Data.Aeson.Types.FromJSON.FromJSON Ssb.Types.Message.Mentions
+ Ssb.Types.Message: instance GHC.Base.Monoid Ssb.Types.Message.Branch
+ Ssb.Types.Message: instance GHC.Base.Monoid Ssb.Types.Message.Mentions
+ Ssb.Types.Message: instance GHC.Classes.Eq Ssb.Types.Message.Branch
+ Ssb.Types.Message: instance GHC.Classes.Eq Ssb.Types.Message.Mentions
+ Ssb.Types.Message: instance GHC.Show.Show Ssb.Types.Message.Branch
+ Ssb.Types.Message: instance GHC.Show.Show Ssb.Types.Message.Mentions
+ Ssb.Types.Message: newtype Branch
+ Ssb.Types.Message: newtype Mentions
- Ssb.Types.Message: About :: Link -> Maybe Text -> Maybe AboutImage -> About
+ Ssb.Types.Message: About :: Link -> Maybe Text -> Maybe AboutImage -> Maybe Text -> About
- Ssb.Types.Message: Mention :: Link -> Mention
+ Ssb.Types.Message: Mention :: Link -> Maybe Text -> Mention
- Ssb.Types.Message: Post :: Text -> Maybe Text -> Maybe MessageLink -> Maybe MessageLink -> Maybe [FeedLink] -> Maybe [Mention] -> Post
+ Ssb.Types.Message: Post :: Text -> Maybe Text -> Maybe MessageLink -> Maybe Branch -> Maybe [FeedLink] -> Maybe Mentions -> Post
- Ssb.Types.Message: [branch] :: Post -> Maybe MessageLink
+ Ssb.Types.Message: [branch] :: Post -> Maybe Branch
- Ssb.Types.Message: [mentions] :: Post -> Maybe [Mention]
+ Ssb.Types.Message: [mentions] :: Post -> Maybe Mentions

Files

CHANGELOG view
@@ -1,3 +1,20 @@+scuttlebutt-types (0.3.0) unstable; urgency=medium++  * Handle about messages whose image field is a string linking to a blob,+    rather than an object.+  * Removed ToJSON instance for Message, until something can be done about+    https://github.com/ssbc/ssb-feed/issues/11+  * Added contentType.+  * Support parsing a Post with multiple branches.+  * Support parsing a Post when its mentions field is an object rather than+    an array.+  * Changes to Message data type to support above changes. (API change)+  * Support parsing a Post that mentions something that is a not a valid+    ssb link.+  * Added description to About.++ -- Joey Hess <id@joeyh.name>  Fri, 06 Oct 2017 14:48:37 -0400+ scuttlebutt-types (0.2.0) unstable; urgency=medium    * Improved Link types.
README.md view
@@ -3,7 +3,10 @@ <https://www.scuttlebutt.nz/>  This library contains Haskell data types for common Secure Scuttlebutt-messages, including JSON serialization.+messages, including JSON deserialization.++(JSON serialization support is blocked by+<https://github.com/ssbc/ssb-feed/issues/11>)  Git repositories: 
scuttlebutt-types.cabal view
@@ -1,5 +1,5 @@ Name: scuttlebutt-types-Version: 0.2.0+Version: 0.3.0 License: BSD3 License-File: LICENSE Author: bkil.hu, Peter Ferenc Hajdu, Joey Hess@@ -15,7 +15,7 @@  optimized for efficient replication for peer to peer protocols.  .  This library contains data types for common Scuttlebutt messages,- including JSON serialization.+ including JSON deserialization.  Library   Hs-Source-Dirs: src@@ -34,7 +34,8 @@     ed25519,     cryptonite,     text,-    memory+    memory,+    vector   Default-Language: Haskell2010  Test-Suite scuttlebutt-types-test
src/Ssb/Types/Message.hs view
@@ -1,14 +1,17 @@-{-# LANGUAGE DeriveGeneric, OverloadedStrings, FlexibleContexts #-}+{-# LANGUAGE DeriveGeneric, OverloadedStrings, FlexibleContexts, GeneralizedNewtypeDeriving #-}  module Ssb.Types.Message ( 	Signature, 	Message(..), 	messageLink, 	AnyContent(..),+	contentType, 	parseMessage, 	narrowParse, 	PrivateContent(..), 	Post(..),+	Branch(..),+	Mentions(..), 	Mention(..), 	About(..), 	AboutImage(..),@@ -30,6 +33,7 @@ import Data.Char import Control.Applicative import qualified Data.Text as T+import qualified Data.Vector as V import qualified Data.ByteString.Lazy as L  import Prelude hiding (sequence)@@ -47,7 +51,6 @@ 	} deriving (Show, Eq, Generic)  instance FromJSON a => FromJSON (Message a)-instance ToJSON a => ToJSON (Message a)  instance Functor Message where 	fmap f m = m { content = f (content m) }@@ -68,6 +71,13 @@ instance FromJSON AnyContent where 	parseJSON = pure . AnyContent +-- | Get the declared type of content in a Message AnyContent.+contentType :: Message AnyContent -> T.Text+contentType = fromMaybe ""+	. parseMaybe (withObject "AnyContent" (.: "type"))+	. fromAnyContent+	. content+ -- | For best efficiency when the type of a message is not known, -- first parse to a Message AnyContent, and then use this function -- with `parseMaybe` or `parseEither` to try to further parse that@@ -101,17 +111,44 @@ 	{ text :: T.Text 	, channel :: Maybe T.Text 	, root :: Maybe MessageLink-	, branch :: Maybe MessageLink+	, branch :: Maybe Branch 	, recps :: Maybe [FeedLink]-	, mentions :: Maybe [Mention]+	, mentions :: Maybe Mentions 	} deriving (Show, Eq, Generic)  instance FromJSON Post where 	parseJSON = parseMessageType "post" (genericParseJSON defaultOptions) --- | A generic reference to other feeds, entities, or blobs+-- | Link to the message in the thread that a Post replies to.+--+-- Generally there is only one link, but sometimes more than one.+newtype Branch = Branch { fromBranch :: [MessageLink] }+	deriving (Show, Eq, Monoid)++instance FromJSON Branch where+	parseJSON v@(String _) = Branch . (:[]) <$> parseJSON v+	parseJSON v@(Array _) = Branch <$> parseJSON v+	parseJSON invalid = typeMismatch "Branch" invalid++newtype Mentions = Mentions { fromMentions :: [Mention] }+	deriving (Show, Eq, Monoid)++-- | Sometimes it's an array of objects.+-- Sometimes there is no array, but a single object.+-- And sometimes the Mention contains an invalid Link; avoid failing on+-- those.+instance FromJSON Mentions where+	parseJSON v@(Object _) = pure $+		Mentions $ catMaybes [parseMaybe parseJSON v]+	parseJSON (Array v) = pure $+		Mentions $ mapMaybe (parseMaybe parseJSON) (V.toList v)+	parseJSON invalid = typeMismatch "Mentions" invalid++-- | A reference to other feeds, entities, or blobs that were mentioned in+-- a Post. data Mention = Mention 	{ mentionLink :: Link+	, mentionName :: Maybe T.Text 	} deriving (Show, Eq, Generic)  instance FromJSON Mention where@@ -124,6 +161,7 @@ 	{ about :: Link 	, name :: Maybe T.Text 	, image :: Maybe AboutImage+	, description :: Maybe T.Text 	} deriving (Show, Eq, Generic)  instance FromJSON About where@@ -137,8 +175,17 @@ 	, aboutImageHeight :: Maybe Int 	} deriving (Show, Eq, Generic) +-- | AboutImage can be encoded as either a JSON object or as a string,+-- which is the BlobLink. instance FromJSON AboutImage where-	parseJSON = parseStrippingPrefix "aboutimage"+	parseJSON o@(Object _) = parseStrippingPrefix "aboutimage" o+	parseJSON s@(String _) = AboutImage+		<$> parseJSON s+		<*> pure Nothing+		<*> pure Nothing+		<*> pure Nothing+		<*> pure Nothing+	parseJSON invalid = typeMismatch "AboutImage" invalid  -- | Contact-messages determine who you are following or blocking. data Contact = Contact
test/MessageSpec.hs view
@@ -68,9 +68,9 @@ 		root (content message) `shouldBe` 			MessageLink <$> parseSha256 "rf1JvoFg1pHE6TkuuMxsjBNevFck7LQvXGhkLMNlaYs=" 		branch (content message) `shouldBe`-			MessageLink <$> parseSha256 "G37a4PUTbysiETQazyYATwLkfn/ZzigmIheAx905MLU="+			Just (Branch [fromJust $ MessageLink <$> parseSha256 "G37a4PUTbysiETQazyYATwLkfn/ZzigmIheAx905MLU="]) 		recps (content message) `shouldBe` Nothing-		map (linkTo . mentionLink) <$> (mentions (content message)) `shouldBe`+		map (linkTo . mentionLink) . fromMentions <$> (mentions (content message)) `shouldBe` 			Just [ "dnr1swLSAgf36g+FzGjNLgmytj2IIyDaYeKZ7F5GdzY=" ]  	it "does not parse content that is not a post" $ do@@ -98,6 +98,23 @@ \  \"signature\": \"mPC156lndHN2oES/UE0GPK/Z8QgFLG8B/bba2TycXzPZZ7IShQhmFiasE0r0ZBTfRmU9KyuVdfwVYogkY2IACA==.sig.ed25519\"\ \}" +altAbout :: ByteString+altAbout = "\+\{\+\  \"previous\": null,\+\  \"author\": \"@t0/CL/qifMsFniGq7fZ0KNjmC5/MLpJpuxPi/fFNvzU=.ed25519\",\+\  \"sequence\": 1,\+\  \"timestamp\": 1491509688475,\+\  \"hash\": \"sha256\",\+\  \"content\": {\+\    \"type\": \"about\",\+\    \"about\": \"@t0/CL/qifMsFniGq7fZ0KNjmC5/MLpJpuxPi/fFNvzU=.ed25519\",\+\    \"image\": \"&+FICZpX7m4zJE99OVgBj/0IPaIH23T9ea8bBDazMsTw=.sha256\",\+\    \"name\": \"jlipps\"\+\  },\+\  \"signature\": \"Qji3DvYtHu5kLs86Cxcor0jNrIC13qGrzqoIrSPCf750WrRKpdbqmFGKOqSiIUVT713i7BSnX7thrc7dXBkKDA==.sig.ed25519\"\+\}"+ aboutSpec :: Spec aboutSpec = describe "about" $ do 	it "extracts message about" $ do@@ -114,6 +131,11 @@ 			Just (Just 512) 		fmap aboutImageHeight (image (content message)) `shouldBe` 			Just (Just 512)+	it "extracts message about with short AboutImage" $ do+		let Just message = (decode altAbout) :: Maybe (Message About)+		fmap aboutImageLink (image (content message)) `shouldBe`+			BlobLink <$> parseSha256 "+FICZpX7m4zJE99OVgBj/0IPaIH23T9ea8bBDazMsTw="+		name (content message) `shouldBe` Just "jlipps"  originalContact :: ByteString originalContact = "\