packages feed

rss-conduit 0.4.3.1 → 0.5.0.0

raw patch · 15 files changed

+541/−351 lines, 15 filesdep +base-compat-batteriesdep −semigroupsdep −singletonsdep −vinyldep ~basedep ~conduitdep ~xml-conduitPVP ok

version bump matches the API change (PVP)

Dependencies added: base-compat-batteries

Dependencies removed: semigroups, singletons, vinyl

Dependency ranges changed: base, conduit, xml-conduit

API changes (from Hackage documentation)

- Text.RSS.Extensions: parseRssChannelExtensions :: ParseRssExtensions e => MonadThrow m => ConduitT Event o m (RssChannelExtensions e)
- Text.RSS.Extensions: parseRssItemExtensions :: ParseRssExtensions e => MonadThrow m => ConduitT Event o m (RssItemExtensions e)
- Text.RSS.Extensions: renderRssChannelExtensions :: Monad m => RenderRssExtensions e => RssChannelExtensions e -> ConduitT () Event m ()
- Text.RSS.Extensions: renderRssItemExtensions :: Monad m => RenderRssExtensions e => RssItemExtensions e -> ConduitT () Event m ()
- Text.RSS.Extensions: type ParseRssExtensions (e :: [*]) = (AllConstrained ParseRssExtension e, SingI e)
- Text.RSS.Extensions: type RenderRssExtensions (e :: [*]) = (AllConstrained RenderRssExtension e)
- Text.RSS.Extensions.Atom: data AtomModule :: *
- Text.RSS.Extensions.Atom: instance Data.Singletons.Internal.SingI Text.RSS.Extensions.Atom.AtomModule
- Text.RSS.Extensions.Atom: instance GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Atom.AtomModule)
- Text.RSS.Extensions.Atom: instance GHC.Classes.Eq (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Atom.AtomModule)
- Text.RSS.Extensions.Atom: instance GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Atom.AtomModule)
- Text.RSS.Extensions.Atom: instance GHC.Generics.Generic (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Atom.AtomModule)
- Text.RSS.Extensions.Atom: instance GHC.Show.Show (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Atom.AtomModule)
- Text.RSS.Extensions.Atom: instance GHC.Show.Show (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Atom.AtomModule)
- Text.RSS.Extensions.Atom: instance Text.RSS.Extensions.ParseRssExtension Text.RSS.Extensions.Atom.AtomModule
- Text.RSS.Extensions.Atom: instance Text.RSS.Extensions.RenderRssExtension Text.RSS.Extensions.Atom.AtomModule
- Text.RSS.Extensions.Content: data ContentModule :: *
- Text.RSS.Extensions.Content: instance Data.Singletons.Internal.SingI Text.RSS.Extensions.Content.ContentModule
- Text.RSS.Extensions.Content: instance GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Content.ContentModule)
- Text.RSS.Extensions.Content: instance GHC.Classes.Eq (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Content.ContentModule)
- Text.RSS.Extensions.Content: instance GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Content.ContentModule)
- Text.RSS.Extensions.Content: instance GHC.Classes.Ord (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Content.ContentModule)
- Text.RSS.Extensions.Content: instance GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Content.ContentModule)
- Text.RSS.Extensions.Content: instance GHC.Generics.Generic (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Content.ContentModule)
- Text.RSS.Extensions.Content: instance GHC.Show.Show (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Content.ContentModule)
- Text.RSS.Extensions.Content: instance GHC.Show.Show (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Content.ContentModule)
- Text.RSS.Extensions.Content: instance Text.RSS.Extensions.ParseRssExtension Text.RSS.Extensions.Content.ContentModule
- Text.RSS.Extensions.Content: instance Text.RSS.Extensions.RenderRssExtension Text.RSS.Extensions.Content.ContentModule
- Text.RSS.Extensions.DublinCore: data DublinCoreModule :: *
- Text.RSS.Extensions.DublinCore: instance Data.Singletons.Internal.SingI Text.RSS.Extensions.DublinCore.DublinCoreModule
- Text.RSS.Extensions.DublinCore: instance GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.DublinCore.DublinCoreModule)
- Text.RSS.Extensions.DublinCore: instance GHC.Classes.Eq (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.DublinCore.DublinCoreModule)
- Text.RSS.Extensions.DublinCore: instance GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.DublinCore.DublinCoreModule)
- Text.RSS.Extensions.DublinCore: instance GHC.Classes.Ord (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.DublinCore.DublinCoreModule)
- Text.RSS.Extensions.DublinCore: instance GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.DublinCore.DublinCoreModule)
- Text.RSS.Extensions.DublinCore: instance GHC.Generics.Generic (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.DublinCore.DublinCoreModule)
- Text.RSS.Extensions.DublinCore: instance GHC.Show.Show (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.DublinCore.DublinCoreModule)
- Text.RSS.Extensions.DublinCore: instance GHC.Show.Show (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.DublinCore.DublinCoreModule)
- Text.RSS.Extensions.DublinCore: instance Text.RSS.Extensions.ParseRssExtension Text.RSS.Extensions.DublinCore.DublinCoreModule
- Text.RSS.Extensions.DublinCore: instance Text.RSS.Extensions.RenderRssExtension Text.RSS.Extensions.DublinCore.DublinCoreModule
- Text.RSS.Extensions.Syndication: data SyndicationModule :: *
- Text.RSS.Extensions.Syndication: instance Data.Singletons.Internal.SingI Text.RSS.Extensions.Syndication.SyndicationModule
- Text.RSS.Extensions.Syndication: instance GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Syndication.SyndicationModule)
- Text.RSS.Extensions.Syndication: instance GHC.Classes.Eq (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Syndication.SyndicationModule)
- Text.RSS.Extensions.Syndication: instance GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Syndication.SyndicationModule)
- Text.RSS.Extensions.Syndication: instance GHC.Classes.Ord (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Syndication.SyndicationModule)
- Text.RSS.Extensions.Syndication: instance GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Syndication.SyndicationModule)
- Text.RSS.Extensions.Syndication: instance GHC.Generics.Generic (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Syndication.SyndicationModule)
- Text.RSS.Extensions.Syndication: instance GHC.Read.Read (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Syndication.SyndicationModule)
- Text.RSS.Extensions.Syndication: instance GHC.Read.Read (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Syndication.SyndicationModule)
- Text.RSS.Extensions.Syndication: instance GHC.Show.Show (Text.RSS.Types.RssChannelExtension Text.RSS.Extensions.Syndication.SyndicationModule)
- Text.RSS.Extensions.Syndication: instance GHC.Show.Show (Text.RSS.Types.RssItemExtension Text.RSS.Extensions.Syndication.SyndicationModule)
- Text.RSS.Extensions.Syndication: instance Text.RSS.Extensions.ParseRssExtension Text.RSS.Extensions.Syndication.SyndicationModule
- Text.RSS.Extensions.Syndication: instance Text.RSS.Extensions.RenderRssExtension Text.RSS.Extensions.Syndication.SyndicationModule
- Text.RSS.Lens: channelExtensionL :: RElem a e (RIndex a e) => Lens' (RssDocument e) (RssChannelExtension a)
- Text.RSS.Lens: itemExtensionL :: RElem a e (RIndex a e) => Lens' (RssItem e) (RssItemExtension a)
- Text.RSS.Types: instance (GHC.Classes.Eq (Text.RSS.Types.RssChannelExtensions e), GHC.Classes.Eq (Text.RSS.Types.RssItemExtensions e)) => GHC.Classes.Eq (Text.RSS.Types.RssDocument e)
- Text.RSS.Types: instance (GHC.Classes.Ord (Text.RSS.Types.RssChannelExtensions e), GHC.Classes.Ord (Text.RSS.Types.RssItemExtensions e)) => GHC.Classes.Ord (Text.RSS.Types.RssDocument e)
- Text.RSS.Types: instance (GHC.Generics.Generic (Text.RSS.Types.RssChannelExtensions e), GHC.Generics.Generic (Text.RSS.Types.RssItemExtensions e)) => GHC.Generics.Generic (Text.RSS.Types.RssDocument e)
- Text.RSS.Types: instance (GHC.Show.Show (Text.RSS.Types.RssChannelExtensions e), GHC.Show.Show (Text.RSS.Types.RssItemExtensions e)) => GHC.Show.Show (Text.RSS.Types.RssDocument e)
- Text.RSS.Types: instance GHC.Classes.Eq (Data.Vinyl.Core.Rec Text.RSS.Types.RssChannelExtension a) => GHC.Classes.Eq (Text.RSS.Types.RssChannelExtensions a)
- Text.RSS.Types: instance GHC.Classes.Eq (Data.Vinyl.Core.Rec Text.RSS.Types.RssItemExtension a) => GHC.Classes.Eq (Text.RSS.Types.RssItemExtensions a)
- Text.RSS.Types: instance GHC.Classes.Eq (Text.RSS.Types.RssItemExtensions e) => GHC.Classes.Eq (Text.RSS.Types.RssItem e)
- Text.RSS.Types: instance GHC.Classes.Ord (Data.Vinyl.Core.Rec Text.RSS.Types.RssChannelExtension a) => GHC.Classes.Ord (Text.RSS.Types.RssChannelExtensions a)
- Text.RSS.Types: instance GHC.Classes.Ord (Data.Vinyl.Core.Rec Text.RSS.Types.RssItemExtension a) => GHC.Classes.Ord (Text.RSS.Types.RssItemExtensions a)
- Text.RSS.Types: instance GHC.Classes.Ord (Text.RSS.Types.RssItemExtensions e) => GHC.Classes.Ord (Text.RSS.Types.RssItem e)
- Text.RSS.Types: instance GHC.Generics.Generic (Data.Vinyl.Core.Rec Text.RSS.Types.RssChannelExtension a) => GHC.Generics.Generic (Text.RSS.Types.RssChannelExtensions a)
- Text.RSS.Types: instance GHC.Generics.Generic (Data.Vinyl.Core.Rec Text.RSS.Types.RssItemExtension a) => GHC.Generics.Generic (Text.RSS.Types.RssItemExtensions a)
- Text.RSS.Types: instance GHC.Generics.Generic (Text.RSS.Types.RssItemExtensions e) => GHC.Generics.Generic (Text.RSS.Types.RssItem e)
- Text.RSS.Types: instance GHC.Read.Read (Data.Vinyl.Core.Rec Text.RSS.Types.RssChannelExtension a) => GHC.Read.Read (Text.RSS.Types.RssChannelExtensions a)
- Text.RSS.Types: instance GHC.Read.Read (Data.Vinyl.Core.Rec Text.RSS.Types.RssItemExtension a) => GHC.Read.Read (Text.RSS.Types.RssItemExtensions a)
- Text.RSS.Types: instance GHC.Show.Show (Data.Vinyl.Core.Rec Text.RSS.Types.RssChannelExtension a) => GHC.Show.Show (Text.RSS.Types.RssChannelExtensions a)
- Text.RSS.Types: instance GHC.Show.Show (Data.Vinyl.Core.Rec Text.RSS.Types.RssItemExtension a) => GHC.Show.Show (Text.RSS.Types.RssItemExtensions a)
- Text.RSS.Types: instance GHC.Show.Show (Text.RSS.Types.RssItemExtensions e) => GHC.Show.Show (Text.RSS.Types.RssItem e)
+ Text.RSS.Extensions: instance Text.RSS.Extensions.ParseRssExtension Text.RSS.Types.NoExtensions
+ Text.RSS.Extensions: instance Text.RSS.Extensions.RenderRssExtension Text.RSS.Types.NoExtensions
+ Text.RSS.Extensions.Atom: AtomModule :: a -> AtomModule a
+ Text.RSS.Extensions.Atom: instance GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension a) => GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Atom.AtomModule a))
+ Text.RSS.Extensions.Atom: instance GHC.Classes.Eq (Text.RSS.Types.RssItemExtension a) => GHC.Classes.Eq (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Atom.AtomModule a))
+ Text.RSS.Extensions.Atom: instance GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension a) => GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Atom.AtomModule a))
+ Text.RSS.Extensions.Atom: instance GHC.Classes.Ord (Text.RSS.Types.RssItemExtension a) => GHC.Classes.Ord (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Atom.AtomModule a))
+ Text.RSS.Extensions.Atom: instance GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension a) => GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Atom.AtomModule a))
+ Text.RSS.Extensions.Atom: instance GHC.Generics.Generic (Text.RSS.Types.RssItemExtension a) => GHC.Generics.Generic (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Atom.AtomModule a))
+ Text.RSS.Extensions.Atom: instance GHC.Show.Show (Text.RSS.Types.RssChannelExtension a) => GHC.Show.Show (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Atom.AtomModule a))
+ Text.RSS.Extensions.Atom: instance GHC.Show.Show (Text.RSS.Types.RssItemExtension a) => GHC.Show.Show (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Atom.AtomModule a))
+ Text.RSS.Extensions.Atom: instance Text.RSS.Extensions.ParseRssExtension a => Text.RSS.Extensions.ParseRssExtension (Text.RSS.Extensions.Atom.AtomModule a)
+ Text.RSS.Extensions.Atom: instance Text.RSS.Extensions.RenderRssExtension a => Text.RSS.Extensions.RenderRssExtension (Text.RSS.Extensions.Atom.AtomModule a)
+ Text.RSS.Extensions.Atom: newtype AtomModule a
+ Text.RSS.Extensions.Content: ContentModule :: a -> ContentModule a
+ Text.RSS.Extensions.Content: instance GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension a) => GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Content.ContentModule a))
+ Text.RSS.Extensions.Content: instance GHC.Classes.Eq (Text.RSS.Types.RssItemExtension a) => GHC.Classes.Eq (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Content.ContentModule a))
+ Text.RSS.Extensions.Content: instance GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension a) => GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Content.ContentModule a))
+ Text.RSS.Extensions.Content: instance GHC.Classes.Ord (Text.RSS.Types.RssItemExtension a) => GHC.Classes.Ord (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Content.ContentModule a))
+ Text.RSS.Extensions.Content: instance GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension a) => GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Content.ContentModule a))
+ Text.RSS.Extensions.Content: instance GHC.Generics.Generic (Text.RSS.Types.RssItemExtension a) => GHC.Generics.Generic (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Content.ContentModule a))
+ Text.RSS.Extensions.Content: instance GHC.Read.Read (Text.RSS.Types.RssChannelExtension a) => GHC.Read.Read (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Content.ContentModule a))
+ Text.RSS.Extensions.Content: instance GHC.Read.Read (Text.RSS.Types.RssItemExtension a) => GHC.Read.Read (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Content.ContentModule a))
+ Text.RSS.Extensions.Content: instance GHC.Show.Show (Text.RSS.Types.RssChannelExtension a) => GHC.Show.Show (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Content.ContentModule a))
+ Text.RSS.Extensions.Content: instance GHC.Show.Show (Text.RSS.Types.RssItemExtension a) => GHC.Show.Show (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Content.ContentModule a))
+ Text.RSS.Extensions.Content: instance Text.RSS.Extensions.ParseRssExtension a => Text.RSS.Extensions.ParseRssExtension (Text.RSS.Extensions.Content.ContentModule a)
+ Text.RSS.Extensions.Content: instance Text.RSS.Extensions.RenderRssExtension a => Text.RSS.Extensions.RenderRssExtension (Text.RSS.Extensions.Content.ContentModule a)
+ Text.RSS.Extensions.Content: newtype ContentModule a
+ Text.RSS.Extensions.DublinCore: DublinCoreModule :: a -> DublinCoreModule a
+ Text.RSS.Extensions.DublinCore: instance GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension a) => GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a))
+ Text.RSS.Extensions.DublinCore: instance GHC.Classes.Eq (Text.RSS.Types.RssItemExtension a) => GHC.Classes.Eq (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a))
+ Text.RSS.Extensions.DublinCore: instance GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension a) => GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a))
+ Text.RSS.Extensions.DublinCore: instance GHC.Classes.Ord (Text.RSS.Types.RssItemExtension a) => GHC.Classes.Ord (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a))
+ Text.RSS.Extensions.DublinCore: instance GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension a) => GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a))
+ Text.RSS.Extensions.DublinCore: instance GHC.Generics.Generic (Text.RSS.Types.RssItemExtension a) => GHC.Generics.Generic (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a))
+ Text.RSS.Extensions.DublinCore: instance GHC.Read.Read (Text.RSS.Types.RssChannelExtension a) => GHC.Read.Read (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a))
+ Text.RSS.Extensions.DublinCore: instance GHC.Read.Read (Text.RSS.Types.RssItemExtension a) => GHC.Read.Read (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a))
+ Text.RSS.Extensions.DublinCore: instance GHC.Read.Read Text.RSS.Extensions.DublinCore.DcMetaData
+ Text.RSS.Extensions.DublinCore: instance GHC.Show.Show (Text.RSS.Types.RssChannelExtension a) => GHC.Show.Show (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a))
+ Text.RSS.Extensions.DublinCore: instance GHC.Show.Show (Text.RSS.Types.RssItemExtension a) => GHC.Show.Show (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a))
+ Text.RSS.Extensions.DublinCore: instance Text.RSS.Extensions.ParseRssExtension a => Text.RSS.Extensions.ParseRssExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a)
+ Text.RSS.Extensions.DublinCore: instance Text.RSS.Extensions.RenderRssExtension a => Text.RSS.Extensions.RenderRssExtension (Text.RSS.Extensions.DublinCore.DublinCoreModule a)
+ Text.RSS.Extensions.DublinCore: newtype DublinCoreModule a
+ Text.RSS.Extensions.Syndication: SyndicationModule :: a -> SyndicationModule a
+ Text.RSS.Extensions.Syndication: instance GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension a) => GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Syndication.SyndicationModule a))
+ Text.RSS.Extensions.Syndication: instance GHC.Classes.Eq (Text.RSS.Types.RssItemExtension a) => GHC.Classes.Eq (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Syndication.SyndicationModule a))
+ Text.RSS.Extensions.Syndication: instance GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension a) => GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Syndication.SyndicationModule a))
+ Text.RSS.Extensions.Syndication: instance GHC.Classes.Ord (Text.RSS.Types.RssItemExtension a) => GHC.Classes.Ord (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Syndication.SyndicationModule a))
+ Text.RSS.Extensions.Syndication: instance GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension a) => GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Syndication.SyndicationModule a))
+ Text.RSS.Extensions.Syndication: instance GHC.Generics.Generic (Text.RSS.Types.RssItemExtension a) => GHC.Generics.Generic (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Syndication.SyndicationModule a))
+ Text.RSS.Extensions.Syndication: instance GHC.Read.Read (Text.RSS.Types.RssChannelExtension a) => GHC.Read.Read (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Syndication.SyndicationModule a))
+ Text.RSS.Extensions.Syndication: instance GHC.Read.Read (Text.RSS.Types.RssItemExtension a) => GHC.Read.Read (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Syndication.SyndicationModule a))
+ Text.RSS.Extensions.Syndication: instance GHC.Show.Show (Text.RSS.Types.RssChannelExtension a) => GHC.Show.Show (Text.RSS.Types.RssChannelExtension (Text.RSS.Extensions.Syndication.SyndicationModule a))
+ Text.RSS.Extensions.Syndication: instance GHC.Show.Show (Text.RSS.Types.RssItemExtension a) => GHC.Show.Show (Text.RSS.Types.RssItemExtension (Text.RSS.Extensions.Syndication.SyndicationModule a))
+ Text.RSS.Extensions.Syndication: instance Text.RSS.Extensions.ParseRssExtension a => Text.RSS.Extensions.ParseRssExtension (Text.RSS.Extensions.Syndication.SyndicationModule a)
+ Text.RSS.Extensions.Syndication: instance Text.RSS.Extensions.RenderRssExtension a => Text.RSS.Extensions.RenderRssExtension (Text.RSS.Extensions.Syndication.SyndicationModule a)
+ Text.RSS.Extensions.Syndication: newtype SyndicationModule a
+ Text.RSS.Types: NoExtensions :: NoExtensions
+ Text.RSS.Types: data NoExtensions
+ Text.RSS.Types: instance (GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension e), GHC.Classes.Eq (Text.RSS.Types.RssItemExtension e)) => GHC.Classes.Eq (Text.RSS.Types.RssDocument e)
+ Text.RSS.Types: instance (GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension e), GHC.Classes.Ord (Text.RSS.Types.RssItemExtension e)) => GHC.Classes.Ord (Text.RSS.Types.RssDocument e)
+ Text.RSS.Types: instance (GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension e), GHC.Generics.Generic (Text.RSS.Types.RssItemExtension e)) => GHC.Generics.Generic (Text.RSS.Types.RssDocument e)
+ Text.RSS.Types: instance (GHC.Show.Show (Text.RSS.Types.RssChannelExtension e), GHC.Show.Show (Text.RSS.Types.RssItemExtension e)) => GHC.Show.Show (Text.RSS.Types.RssDocument e)
+ Text.RSS.Types: instance GHC.Classes.Eq (Text.RSS.Types.RssChannelExtension Text.RSS.Types.NoExtensions)
+ Text.RSS.Types: instance GHC.Classes.Eq (Text.RSS.Types.RssItemExtension Text.RSS.Types.NoExtensions)
+ Text.RSS.Types: instance GHC.Classes.Eq (Text.RSS.Types.RssItemExtension e) => GHC.Classes.Eq (Text.RSS.Types.RssItem e)
+ Text.RSS.Types: instance GHC.Classes.Eq Text.RSS.Types.NoExtensions
+ Text.RSS.Types: instance GHC.Classes.Ord (Text.RSS.Types.RssChannelExtension Text.RSS.Types.NoExtensions)
+ Text.RSS.Types: instance GHC.Classes.Ord (Text.RSS.Types.RssItemExtension Text.RSS.Types.NoExtensions)
+ Text.RSS.Types: instance GHC.Classes.Ord (Text.RSS.Types.RssItemExtension e) => GHC.Classes.Ord (Text.RSS.Types.RssItem e)
+ Text.RSS.Types: instance GHC.Classes.Ord Text.RSS.Types.NoExtensions
+ Text.RSS.Types: instance GHC.Generics.Generic (Text.RSS.Types.RssChannelExtension Text.RSS.Types.NoExtensions)
+ Text.RSS.Types: instance GHC.Generics.Generic (Text.RSS.Types.RssItemExtension Text.RSS.Types.NoExtensions)
+ Text.RSS.Types: instance GHC.Generics.Generic (Text.RSS.Types.RssItemExtension e) => GHC.Generics.Generic (Text.RSS.Types.RssItem e)
+ Text.RSS.Types: instance GHC.Generics.Generic Text.RSS.Types.NoExtensions
+ Text.RSS.Types: instance GHC.Read.Read (Text.RSS.Types.RssChannelExtension Text.RSS.Types.NoExtensions)
+ Text.RSS.Types: instance GHC.Read.Read (Text.RSS.Types.RssItemExtension Text.RSS.Types.NoExtensions)
+ Text.RSS.Types: instance GHC.Read.Read Text.RSS.Types.NoExtensions
+ Text.RSS.Types: instance GHC.Show.Show (Text.RSS.Types.RssChannelExtension Text.RSS.Types.NoExtensions)
+ Text.RSS.Types: instance GHC.Show.Show (Text.RSS.Types.RssItemExtension Text.RSS.Types.NoExtensions)
+ Text.RSS.Types: instance GHC.Show.Show (Text.RSS.Types.RssItemExtension e) => GHC.Show.Show (Text.RSS.Types.RssItem e)
+ Text.RSS.Types: instance GHC.Show.Show Text.RSS.Types.NoExtensions
- Text.RSS.Conduit.Parse: rssDocument :: ParseRssExtensions e => MonadThrow m => ConduitM Event o m (Maybe (RssDocument e))
+ Text.RSS.Conduit.Parse: rssDocument :: ParseRssExtension e => MonadThrow m => ConduitM Event o m (Maybe (RssDocument e))
- Text.RSS.Conduit.Parse: rssItem :: ParseRssExtensions e => MonadThrow m => ConduitM Event o m (Maybe (RssItem e))
+ Text.RSS.Conduit.Parse: rssItem :: ParseRssExtension e => MonadThrow m => ConduitM Event o m (Maybe (RssItem e))
- Text.RSS.Conduit.Render: renderRssDocument :: Monad m => RenderRssExtensions e => RssDocument e -> ConduitT () Event m ()
+ Text.RSS.Conduit.Render: renderRssDocument :: Monad m => RenderRssExtension e => RssDocument e -> ConduitT () Event m ()
- Text.RSS.Conduit.Render: renderRssItem :: Monad m => RenderRssExtensions e => RssItem e -> ConduitT () Event m ()
+ Text.RSS.Conduit.Render: renderRssItem :: Monad m => RenderRssExtension e => RssItem e -> ConduitT () Event m ()
- Text.RSS.Extensions.DublinCore: channelDcMetaData :: RssChannelExtension DublinCoreModule -> DcMetaData
+ Text.RSS.Extensions.DublinCore: channelDcMetaData :: RssChannelExtension (DublinCoreModule a) -> DcMetaData
- Text.RSS.Extensions.DublinCore: itemDcMetaData :: RssItemExtension DublinCoreModule -> DcMetaData
+ Text.RSS.Extensions.DublinCore: itemDcMetaData :: RssItemExtension (DublinCoreModule a) -> DcMetaData
- Text.RSS.Lens: channelExtensionsL :: Functor f => (RssChannelExtensions extensions -> f (RssChannelExtensions extensions)) -> RssDocument extensions -> f (RssDocument extensions)
+ Text.RSS.Lens: channelExtensionsL :: Functor f => (RssChannelExtension extensions -> f (RssChannelExtension extensions)) -> RssDocument extensions -> f (RssDocument extensions)
- Text.RSS.Lens: itemExtensionsL :: Functor f => (RssItemExtensions extensions1 -> f (RssItemExtensions extensions2)) -> RssItem extensions1 -> f (RssItem extensions2)
+ Text.RSS.Lens: itemExtensionsL :: Functor f => (RssItemExtension extensions1 -> f (RssItemExtension extensions2)) -> RssItem extensions1 -> f (RssItem extensions2)
- Text.RSS.Types: RssDocument :: Version -> Text -> RssURI -> Text -> [RssItem extensions] -> Text -> Text -> Text -> Text -> Maybe UTCTime -> Maybe UTCTime -> [RssCategory] -> Text -> Maybe RssURI -> Maybe RssCloud -> Maybe Int -> Maybe RssImage -> Text -> Maybe RssTextInput -> Set Hour -> Set Day -> RssChannelExtensions extensions -> RssDocument
+ Text.RSS.Types: RssDocument :: Version -> Text -> RssURI -> Text -> [RssItem extensions] -> Text -> Text -> Text -> Text -> Maybe UTCTime -> Maybe UTCTime -> [RssCategory] -> Text -> Maybe RssURI -> Maybe RssCloud -> Maybe Int -> Maybe RssImage -> Text -> Maybe RssTextInput -> Set Hour -> Set Day -> RssChannelExtension extensions -> RssDocument extensions
- Text.RSS.Types: RssItem :: Text -> Maybe RssURI -> Text -> Text -> [RssCategory] -> Maybe RssURI -> [RssEnclosure] -> Maybe RssGuid -> Maybe UTCTime -> Maybe RssSource -> RssItemExtensions extensions -> RssItem
+ Text.RSS.Types: RssItem :: Text -> Maybe RssURI -> Text -> Text -> [RssCategory] -> Maybe RssURI -> [RssEnclosure] -> Maybe RssGuid -> Maybe UTCTime -> Maybe RssSource -> RssItemExtension extensions -> RssItem extensions
- Text.RSS.Types: [channelCategories] :: RssDocument -> [RssCategory]
+ Text.RSS.Types: [channelCategories] :: RssDocument extensions -> [RssCategory]
- Text.RSS.Types: [channelCloud] :: RssDocument -> Maybe RssCloud
+ Text.RSS.Types: [channelCloud] :: RssDocument extensions -> Maybe RssCloud
- Text.RSS.Types: [channelCopyright] :: RssDocument -> Text
+ Text.RSS.Types: [channelCopyright] :: RssDocument extensions -> Text
- Text.RSS.Types: [channelDescription] :: RssDocument -> Text
+ Text.RSS.Types: [channelDescription] :: RssDocument extensions -> Text
- Text.RSS.Types: [channelDocs] :: RssDocument -> Maybe RssURI
+ Text.RSS.Types: [channelDocs] :: RssDocument extensions -> Maybe RssURI
- Text.RSS.Types: [channelExtensions] :: RssDocument -> RssChannelExtensions extensions
+ Text.RSS.Types: [channelExtensions] :: RssDocument extensions -> RssChannelExtension extensions
- Text.RSS.Types: [channelGenerator] :: RssDocument -> Text
+ Text.RSS.Types: [channelGenerator] :: RssDocument extensions -> Text
- Text.RSS.Types: [channelImage] :: RssDocument -> Maybe RssImage
+ Text.RSS.Types: [channelImage] :: RssDocument extensions -> Maybe RssImage
- Text.RSS.Types: [channelItems] :: RssDocument -> [RssItem extensions]
+ Text.RSS.Types: [channelItems] :: RssDocument extensions -> [RssItem extensions]
- Text.RSS.Types: [channelLanguage] :: RssDocument -> Text
+ Text.RSS.Types: [channelLanguage] :: RssDocument extensions -> Text
- Text.RSS.Types: [channelLastBuildDate] :: RssDocument -> Maybe UTCTime
+ Text.RSS.Types: [channelLastBuildDate] :: RssDocument extensions -> Maybe UTCTime
- Text.RSS.Types: [channelLink] :: RssDocument -> RssURI
+ Text.RSS.Types: [channelLink] :: RssDocument extensions -> RssURI
- Text.RSS.Types: [channelManagingEditor] :: RssDocument -> Text
+ Text.RSS.Types: [channelManagingEditor] :: RssDocument extensions -> Text
- Text.RSS.Types: [channelPubDate] :: RssDocument -> Maybe UTCTime
+ Text.RSS.Types: [channelPubDate] :: RssDocument extensions -> Maybe UTCTime
- Text.RSS.Types: [channelRating] :: RssDocument -> Text
+ Text.RSS.Types: [channelRating] :: RssDocument extensions -> Text
- Text.RSS.Types: [channelSkipDays] :: RssDocument -> Set Day
+ Text.RSS.Types: [channelSkipDays] :: RssDocument extensions -> Set Day
- Text.RSS.Types: [channelSkipHours] :: RssDocument -> Set Hour
+ Text.RSS.Types: [channelSkipHours] :: RssDocument extensions -> Set Hour
- Text.RSS.Types: [channelTextInput] :: RssDocument -> Maybe RssTextInput
+ Text.RSS.Types: [channelTextInput] :: RssDocument extensions -> Maybe RssTextInput
- Text.RSS.Types: [channelTitle] :: RssDocument -> Text
+ Text.RSS.Types: [channelTitle] :: RssDocument extensions -> Text
- Text.RSS.Types: [channelTtl] :: RssDocument -> Maybe Int
+ Text.RSS.Types: [channelTtl] :: RssDocument extensions -> Maybe Int
- Text.RSS.Types: [channelWebmaster] :: RssDocument -> Text
+ Text.RSS.Types: [channelWebmaster] :: RssDocument extensions -> Text
- Text.RSS.Types: [documentVersion] :: RssDocument -> Version
+ Text.RSS.Types: [documentVersion] :: RssDocument extensions -> Version
- Text.RSS.Types: [itemAuthor] :: RssItem -> Text
+ Text.RSS.Types: [itemAuthor] :: RssItem extensions -> Text
- Text.RSS.Types: [itemCategories] :: RssItem -> [RssCategory]
+ Text.RSS.Types: [itemCategories] :: RssItem extensions -> [RssCategory]
- Text.RSS.Types: [itemComments] :: RssItem -> Maybe RssURI
+ Text.RSS.Types: [itemComments] :: RssItem extensions -> Maybe RssURI
- Text.RSS.Types: [itemDescription] :: RssItem -> Text
+ Text.RSS.Types: [itemDescription] :: RssItem extensions -> Text
- Text.RSS.Types: [itemEnclosure] :: RssItem -> [RssEnclosure]
+ Text.RSS.Types: [itemEnclosure] :: RssItem extensions -> [RssEnclosure]
- Text.RSS.Types: [itemExtensions] :: RssItem -> RssItemExtensions extensions
+ Text.RSS.Types: [itemExtensions] :: RssItem extensions -> RssItemExtension extensions
- Text.RSS.Types: [itemGuid] :: RssItem -> Maybe RssGuid
+ Text.RSS.Types: [itemGuid] :: RssItem extensions -> Maybe RssGuid
- Text.RSS.Types: [itemLink] :: RssItem -> Maybe RssURI
+ Text.RSS.Types: [itemLink] :: RssItem extensions -> Maybe RssURI
- Text.RSS.Types: [itemPubDate] :: RssItem -> Maybe UTCTime
+ Text.RSS.Types: [itemPubDate] :: RssItem extensions -> Maybe UTCTime
- Text.RSS.Types: [itemSource] :: RssItem -> Maybe RssSource
+ Text.RSS.Types: [itemSource] :: RssItem extensions -> Maybe RssSource
- Text.RSS.Types: [itemTitle] :: RssItem -> Text
+ Text.RSS.Types: [itemTitle] :: RssItem extensions -> Text
- Text.RSS.Types: data RssDocument (extensions :: [*])
+ Text.RSS.Types: data RssDocument extensions
- Text.RSS.Types: data RssItem (extensions :: [*])
+ Text.RSS.Types: data RssItem extensions
- Text.RSS.Types: data family RssItemExtensions (extensionTags :: [*]) :: *
+ Text.RSS.Types: data family RssItemExtension extensionTag :: *
- Text.RSS.Types: type RssDocument' = RssDocument '[]
+ Text.RSS.Types: type RssDocument' = RssDocument NoExtensions
- Text.RSS.Types: type RssItem' = RssItem '[]
+ Text.RSS.Types: type RssItem' = RssItem NoExtensions
- Text.RSS1.Conduit.Parse: rss1Document :: ParseRssExtensions e => MonadCatch m => ConduitM Event o m (Maybe (RssDocument e))
+ Text.RSS1.Conduit.Parse: rss1Document :: ParseRssExtension e => MonadCatch m => ConduitM Event o m (Maybe (RssDocument e))
- Text.RSS1.Conduit.Parse: rss1Item :: ParseRssExtensions e => MonadCatch m => ConduitM Event o m (Maybe (RssItem e))
+ Text.RSS1.Conduit.Parse: rss1Item :: ParseRssExtension e => MonadCatch m => ConduitM Event o m (Maybe (RssItem e))

Files

LICENSE view
@@ -1,13 +1,121 @@-DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE-Version 2, December 2004+Creative Commons Legal Code -Copyright (C) 2015 koral <koral at mailoo dot org>+CC0 1.0 Universal -Everyone is permitted to copy and distribute verbatim or modified-copies of this license document, and changing it is allowed as long-as the name is changed.+    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE+    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN+    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS+    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES+    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS+    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM+    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED+    HEREUNDER. -DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE-TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION+Statement of Purpose -0. You just DO WHAT THE FUCK YOU WANT TO.+The laws of most jurisdictions throughout the world automatically confer+exclusive Copyright and Related Rights (defined below) upon the creator+and subsequent owner(s) (each and all, an "owner") of an original work of+authorship and/or a database (each, a "Work").++Certain owners wish to permanently relinquish those rights to a Work for+the purpose of contributing to a commons of creative, cultural and+scientific works ("Commons") that the public can reliably and without fear+of later claims of infringement build upon, modify, incorporate in other+works, reuse and redistribute as freely as possible in any form whatsoever+and for any purposes, including without limitation commercial purposes.+These owners may contribute to the Commons to promote the ideal of a free+culture and the further production of creative, cultural and scientific+works, or to gain reputation or greater distribution for their Work in+part through the use and efforts of others.++For these and/or other purposes and motivations, and without any+expectation of additional consideration or compensation, the person+associating CC0 with a Work (the "Affirmer"), to the extent that he or she+is an owner of Copyright and Related Rights in the Work, voluntarily+elects to apply CC0 to the Work and publicly distribute the Work under its+terms, with knowledge of his or her Copyright and Related Rights in the+Work and the meaning and intended legal effect of CC0 on those rights.++1. Copyright and Related Rights. A Work made available under CC0 may be+protected by copyright and related or neighboring rights ("Copyright and+Related Rights"). Copyright and Related Rights include, but are not+limited to, the following:++  i. the right to reproduce, adapt, distribute, perform, display,+     communicate, and translate a Work;+ ii. moral rights retained by the original author(s) and/or performer(s);+iii. publicity and privacy rights pertaining to a person's image or+     likeness depicted in a Work;+ iv. rights protecting against unfair competition in regards to a Work,+     subject to the limitations in paragraph 4(a), below;+  v. rights protecting the extraction, dissemination, use and reuse of data+     in a Work;+ vi. database rights (such as those arising under Directive 96/9/EC of the+     European Parliament and of the Council of 11 March 1996 on the legal+     protection of databases, and under any national implementation+     thereof, including any amended or successor version of such+     directive); and+vii. other similar, equivalent or corresponding rights throughout the+     world based on applicable law or treaty, and any national+     implementations thereof.++2. Waiver. To the greatest extent permitted by, but not in contravention+of, applicable law, Affirmer hereby overtly, fully, permanently,+irrevocably and unconditionally waives, abandons, and surrenders all of+Affirmer's Copyright and Related Rights and associated claims and causes+of action, whether now known or unknown (including existing as well as+future claims and causes of action), in the Work (i) in all territories+worldwide, (ii) for the maximum duration provided by applicable law or+treaty (including future time extensions), (iii) in any current or future+medium and for any number of copies, and (iv) for any purpose whatsoever,+including without limitation commercial, advertising or promotional+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each+member of the public at large and to the detriment of Affirmer's heirs and+successors, fully intending that such Waiver shall not be subject to+revocation, rescission, cancellation, termination, or any other legal or+equitable action to disrupt the quiet enjoyment of the Work by the public+as contemplated by Affirmer's express Statement of Purpose.++3. Public License Fallback. Should any part of the Waiver for any reason+be judged legally invalid or ineffective under applicable law, then the+Waiver shall be preserved to the maximum extent permitted taking into+account Affirmer's express Statement of Purpose. In addition, to the+extent the Waiver is so judged Affirmer hereby grants to each affected+person a royalty-free, non transferable, non sublicensable, non exclusive,+irrevocable and unconditional license to exercise Affirmer's Copyright and+Related Rights in the Work (i) in all territories worldwide, (ii) for the+maximum duration provided by applicable law or treaty (including future+time extensions), (iii) in any current or future medium and for any number+of copies, and (iv) for any purpose whatsoever, including without+limitation commercial, advertising or promotional purposes (the+"License"). The License shall be deemed effective as of the date CC0 was+applied by Affirmer to the Work. Should any part of the License for any+reason be judged legally invalid or ineffective under applicable law, such+partial invalidity or ineffectiveness shall not invalidate the remainder+of the License, and in such case Affirmer hereby affirms that he or she+will not (i) exercise any of his or her remaining Copyright and Related+Rights in the Work or (ii) assert any associated claims and causes of+action with respect to the Work, in either case contrary to Affirmer's+express Statement of Purpose.++4. Limitations and Disclaimers.++ a. No trademark or patent rights held by Affirmer are waived, abandoned,+    surrendered, licensed or otherwise affected by this document.+ b. Affirmer offers the Work as-is and makes no representations or+    warranties of any kind concerning the Work, express, implied,+    statutory or otherwise, including without limitation warranties of+    title, merchantability, fitness for a particular purpose, non+    infringement, or the absence of latent or other defects, accuracy, or+    the present or absence of errors, whether or not discoverable, all to+    the greatest extent permissible under applicable law.+ c. Affirmer disclaims responsibility for clearing rights of other persons+    that may apply to the Work or any use thereof, including without+    limitation any person's Copyright and Related Rights in the Work.+    Further, Affirmer disclaims responsibility for obtaining any necessary+    consents, permissions or other rights required for any use of the+    Work.+ d. Affirmer understands and acknowledges that Creative Commons is not a+    party to this document and has no duty or obligation with respect to+    this CC0 or use of the Work.
rss-conduit.cabal view
@@ -1,15 +1,16 @@+cabal-version: 2.2 name: rss-conduit-version: 0.4.3.1-cabal-version: >=1.10+version: 0.5.0.0 build-type: Simple-license: PublicDomain+license: CC0-1.0 license-file: LICENSE-maintainer: chahine.moreau@gmail.com+author: koral+maintainer: mail@cmoreau.info+bug-reports: https://github.com/k0ral/rss-conduit/issues synopsis: Streaming parser/renderer for the RSS standard.-description:-    Cf README file.+description: Cf README file. category: XML, Conduit-author: chahine.moreau@gmail.com+tested-with: GHC <8.9 && >=8.4.2 extra-source-files:     README.md @@ -22,10 +23,13 @@   manual: True   default: False +common common+    build-depends: base >=4.7 && <5, base-compat-batteries+    default-language: Haskell2010++ library-    if impl(ghc <8)-        build-depends:-            semigroups -any+    import: common     exposed-modules:         Text.RSS1.Conduit.Parse         Text.RSS.Conduit.Parse@@ -40,7 +44,6 @@         Text.RSS.Types     build-depends:         atom-conduit >=0.5,-        base >=4.8 && <5,         conduit >= 1.3,         conduit-combinators -any,         containers -any,@@ -48,24 +51,21 @@         safe-exceptions -any,         lens-simple -any,         safe -any,-        singletons -any,         text -any,         time >=1.5,         timerep >=2.0,         uri-bytestring >=0.2,-        vinyl >= 0.9,         xml-conduit >=1.5,         xml-types -any-    default-language: Haskell2010     hs-source-dirs: src -test-suite  Tests+test-suite tests+    import: common     type: exitcode-stdio-1.0     main-is: Main.hs     build-depends:-        rss-conduit -any,+        rss-conduit,         atom-conduit >=0.5,-        base >=4.8 && <5,         blaze-builder -any,         bytestring -any,         conduit -any,@@ -75,35 +75,50 @@         filepath -any,         lens-simple -any,         mono-traversable -any,-        QuickCheck -any,-        quickcheck-instances -any,         resourcet -any,         safe-exceptions -any,-        singletons -any,         tasty -any,         tasty-golden -any,         tasty-hunit -any,+        time >=1.5,+        text -any,+        uri-bytestring >=0.2,+        xml-conduit >=1.3,+        xml-types -any+    hs-source-dirs: test++test-suite quickcheck-tests+    import: common+    type: exitcode-stdio-1.0+    main-is: QuickCheck.hs+    build-depends:+        rss-conduit,+        atom-conduit >=0.5,+        blaze-builder -any,+        bytestring -any,+        conduit -any,+        dublincore-xml-conduit -any,+        filepath -any,+        QuickCheck -any,+        quickcheck-instances -any,+        tasty -any,         tasty-quickcheck -any,         time >=1.5,         text -any,         uri-bytestring >=0.2,-        vinyl -any,         xml-conduit >=1.3,         xml-types -any-    default-language: Haskell2010     hs-source-dirs: test     other-modules:         Arbitrary  test-suite hlint+    import: common     if flag(enable-hlint-test)       buildable: True     else       buildable: False     type: exitcode-stdio-1.0     main-is: HLint.hs-    build-depends:-        base >=4.8,-        hlint -any-    default-language: Haskell2010+    build-depends: hlint -any     hs-source-dirs: test
src/Text/RSS/Conduit/Parse.hs view
@@ -205,7 +205,7 @@ -- | Parse an @\<item\>@ element. -- -- RSS extensions are automatically parsed based on the inferred result type.-rssItem :: ParseRssExtensions e => MonadThrow m => ConduitM Event o m (Maybe (RssItem e))+rssItem :: ParseRssExtension e => MonadThrow m => ConduitM Event o m (Maybe (RssItem e)) rssItem = tagIgnoreAttrs "item" $ (manyYield' (choose piece) .| parser) <* many ignoreAnyTreeContent where   parser = getZipConduit $ RssItem     <$> ZipConduit (projectC _ItemTitle .| headDefC "")@@ -218,7 +218,7 @@     <*> ZipConduit (projectC _ItemGuid .| headC)     <*> ZipConduit (projectC _ItemPubDate .| headC)     <*> ZipConduit (projectC _ItemSource .| headC)-    <*> ZipConduit (projectC _ItemOther .| concatC .| parseRssItemExtensions)+    <*> ZipConduit (projectC _ItemOther .| concatC .| parseRssItemExtension)   piece = [ fmap ItemTitle <$> tagIgnoreAttrs "title" content           , fmap ItemLink <$> tagIgnoreAttrs "link" (content >>= asRssURI)           , fmap ItemDescription <$> tagIgnoreAttrs "description" content@@ -247,7 +247,7 @@ -- | Parse an @\<rss\>@ element. -- -- RSS extensions are automatically parsed based on the inferred result type.-rssDocument :: ParseRssExtensions e => MonadThrow m => ConduitM Event o m (Maybe (RssDocument e))+rssDocument :: ParseRssExtension e => MonadThrow m => ConduitM Event o m (Maybe (RssDocument e)) rssDocument = tagName' "rss" attributes $ \version -> force "Missing <channel>" $ tagIgnoreAttrs "channel" (manyYield' (choose piece) .| parser version) <* many ignoreAnyTreeContent where   parser version = getZipConduit $ RssDocument version     <$> ZipConduit (projectC _ChannelTitle .| headRequiredC "Missing <title> element")@@ -270,7 +270,7 @@     <*> ZipConduit (projectC _ChannelTextInput .| headC)     <*> ZipConduit (projectC _ChannelSkipHours .| headDefC mempty)     <*> ZipConduit (projectC _ChannelSkipDays .| headDefC mempty)-    <*> ZipConduit (projectC _ChannelOther .| concatC .| parseRssChannelExtensions)+    <*> ZipConduit (projectC _ChannelOther .| concatC .| parseRssChannelExtension)   piece = [ fmap ChannelTitle <$> tagIgnoreAttrs "title" content           , fmap ChannelLink <$> tagIgnoreAttrs "link" (content >>= asRssURI)           , fmap ChannelDescription <$> tagIgnoreAttrs "description" content
src/Text/RSS/Conduit/Render.hs view
@@ -40,7 +40,7 @@ -- }}}  -- | Render the top-level @\<rss\>@ element.-renderRssDocument :: Monad m => RenderRssExtensions e => RssDocument e -> ConduitT () Event m ()+renderRssDocument :: Monad m => RenderRssExtension e => RssDocument e -> ConduitT () Event m () renderRssDocument d = tag "rss" (attr "version" . pack . showVersion $ d^.documentVersionL) $   tag "channel" mempty $ do     textTag "title" $ d^.channelTitleL@@ -63,10 +63,10 @@     renderRssSkipHours $ d^.channelSkipHoursL     renderRssSkipDays $ d^.channelSkipDaysL     forM_ (d^..channelItemsL) renderRssItem-    renderRssChannelExtensions $ d^.channelExtensionsL+    renderRssChannelExtension $ d^.channelExtensionsL  -- | Render an @\<item\>@ element.-renderRssItem :: Monad m => RenderRssExtensions e => RssItem e -> ConduitT () Event m ()+renderRssItem :: Monad m => RenderRssExtension e => RssItem e -> ConduitT () Event m () renderRssItem i = tag "item" mempty $ do   optionalTextTag "title" $ i^.itemTitleL   forM_ (i^.itemLinkL) $ textTag "link" . renderRssURI@@ -78,7 +78,7 @@   forM_ (i^.itemGuidL) renderRssGuid   forM_ (i^.itemPubDateL) $ dateTag "pubDate"   forM_ (i^.itemSourceL) renderRssSource-  renderRssItemExtensions $ i^.itemExtensionsL+  renderRssItemExtension $ i^.itemExtensionsL  -- | Render a @\<source\>@ element. renderRssSource :: (Monad m) => RssSource -> ConduitT () Event m ()
src/Text/RSS/Extensions.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE ConstraintKinds     #-}-{-# LANGUAGE DataKinds           #-} {-# LANGUAGE FlexibleContexts    #-} {-# LANGUAGE FlexibleInstances   #-} {-# LANGUAGE RankNTypes          #-}@@ -8,25 +6,53 @@ {-# LANGUAGE TypeOperators       #-} -- | Support for RSS extensions. -- Cf specification at <http://web.resource.org/rss/1.0/modules/>.+--+-- To implement an RSS extension:+--+-- - Create a data-type, that will be used as a tag to identify the extension.+--   To allow stacking multiple extensions, your data-type should have kind * -> *+--+--   > data MyExtension otherExtensions = MyExtension otherExtensions+--+-- - Implement extension types for @\<channel\>@ and @\<item\>@ elements:+--+--   > data instance RssChannelExtension (MyExtension e) = MyExtensionChannel+--   >   { -- ... add your fields ...+--   >   , otherChannelExtensions :: RssChannelExtension e+--   >   }+--   >+--   > data instance RssItemExtension (MyExtension e) = MyExtensionItem+--   >   { -- ... add your fields ...+--   >   , otherItemExtensions :: RssItemExtension e+--   >   }+--+-- - Implement 'ParseRssExtension' and 'RenderRssExtension' type classes:+--+--   > -- Parser should rely on ZipConduit to be order-insensitive+--   > instance ParseRssExtension e => ParseRssExtension (MyExtension e) where+--   >   parseRssChannelExtension = getZipConduit $ MyExtensionChannel+--   >     <$> ZipConduit -- ... parse fields+--   >     <*> ZipConduit parseRssChannelExtension+--   >   parseRssItemExtension = -- ... similarly+--   >+--   > instance RenderRssExtension e => RenderRssExtension (MyExtension e) where+--   >   renderRssChannelExtension (MyExtensionChannel {- fields -} otherChannelExtensions) = do+--   >     -- ... render fields+--   >     renderRssChannelExtension otherChannelExtensions+--   >   renderRssItemExtension (MyExtensionItem {- fields -} otherItemExtensions) = -- ... similarly module Text.RSS.Extensions where  -- {{{ Imports-import           Control.Exception.Safe       as Exception+import           Control.Exception.Safe  as Exception import           Data.Conduit import           Data.Maybe import           Data.Proxy-import           Data.Singletons-import           Data.Singletons.Prelude.Bool-import           Data.Singletons.Prelude.Eq-import           Data.Singletons.Prelude.List import           Data.Text-import           Data.Vinyl.Core-import           Data.Vinyl.TypeLevel import           Data.XML.Types import           GHC.Generics import           Text.Atom.Conduit.Parse import           Text.Atom.Types-import           Text.Read                    (readMaybe)+import           Text.Read               (readMaybe) import           Text.RSS.Types import           Text.XML.Stream.Parse import           URI.ByteString@@ -43,28 +69,9 @@   -- Therefore, it is expected to ignore 'Event's unrelated to the RSS extension.   parseRssItemExtension :: MonadThrow m => ConduitT Event o m (RssItemExtension a) --- | Requirement on a list of extension tags to be able to parse and combine them.-type ParseRssExtensions (e :: [*]) = (AllConstrained ParseRssExtension e, SingI e)---- | Parse a combination of RSS extensions at @\<channel\>@ level.-parseRssChannelExtensions :: ParseRssExtensions e => MonadThrow m => ConduitT Event o m (RssChannelExtensions e)-parseRssChannelExtensions = f sing where-  f :: AllConstrained ParseRssExtension e => MonadThrow m-    => Sing e -> ConduitT Event o m (RssChannelExtensions e)-  f SNil = return $ RssChannelExtensions RNil-  f (SCons _ es) = fmap RssChannelExtensions $ getZipConduit $ (:&)-    <$> ZipConduit parseRssChannelExtension-    <*> ZipConduit (rssChannelExtension <$> f es)---- | Parse a combination of RSS extensions at @\<item\>@ level.-parseRssItemExtensions :: ParseRssExtensions e => MonadThrow m => ConduitT Event o m (RssItemExtensions e)-parseRssItemExtensions = f sing where-  f :: AllConstrained ParseRssExtension e => MonadThrow m-    => Sing e -> ConduitT Event o m (RssItemExtensions e)-  f SNil = return $ RssItemExtensions RNil-  f (SCons _ es) = fmap RssItemExtensions $ getZipConduit $ (:&)-    <$> ZipConduit parseRssItemExtension-    <*> ZipConduit (rssItemExtension <$> f es)+instance ParseRssExtension NoExtensions where+  parseRssChannelExtension = pure NoChannelExtensions+  parseRssItemExtension = pure NoItemExtensions   -- * Rendering@@ -76,19 +83,6 @@   -- | Render extension for the @\<item\>@ element.   renderRssItemExtension :: Monad m => RssItemExtension e -> ConduitT () Event m () --- | Requirement on a list of extension tags to be able to render them.-type RenderRssExtensions (e :: [*]) = (AllConstrained RenderRssExtension e)---- | Render a set of @\<channel\>@ extensions.-renderRssChannelExtensions :: Monad m => RenderRssExtensions e => RssChannelExtensions e -> ConduitT () Event m ()-renderRssChannelExtensions (RssChannelExtensions RNil) = pure ()-renderRssChannelExtensions (RssChannelExtensions (a :& t)) = do-  renderRssChannelExtension a-  renderRssChannelExtensions (RssChannelExtensions t)---- | Render a set of @\<item\>@ extensions.-renderRssItemExtensions :: Monad m => RenderRssExtensions e => RssItemExtensions e -> ConduitT () Event m ()-renderRssItemExtensions (RssItemExtensions RNil) = pure ()-renderRssItemExtensions (RssItemExtensions (a :& t)) = do-  renderRssItemExtension a-  renderRssItemExtensions (RssItemExtensions t)+instance RenderRssExtension NoExtensions where+  renderRssChannelExtension = const $ pure ()+  renderRssItemExtension = const $ pure ()
src/Text/RSS/Extensions/Atom.hs view
@@ -1,8 +1,10 @@-{-# LANGUAGE DataKinds      #-}-{-# LANGUAGE DeriveGeneric  #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE RankNTypes     #-}-{-# LANGUAGE TypeFamilies   #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE FlexibleContexts   #-}+{-# LANGUAGE FlexibleInstances  #-}+{-# LANGUAGE RankNTypes         #-}+{-# LANGUAGE RecordWildCards    #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeFamilies       #-} -- | __Atom__ extension for RSS. -- Cf specification at <http://www.rssboard.org/rss-profile#namespace-elements-atom>. module Text.RSS.Extensions.Atom where@@ -11,8 +13,7 @@ import           Text.RSS.Extensions import           Text.RSS.Types -import           Conduit                  (headC, (.|))-import           Data.Singletons+import           Conduit                  (ZipConduit (..), headC, (.|)) import           GHC.Generics import           Text.Atom.Conduit.Parse import           Text.Atom.Conduit.Render@@ -21,21 +22,44 @@ -- }}}  -- | __Atom__ tag type.-data AtomModule :: *+newtype AtomModule a = AtomModule a -data instance Sing AtomModule = SAtomModule+instance ParseRssExtension a => ParseRssExtension (AtomModule a) where+  parseRssChannelExtension = getZipConduit $ AtomChannel+    <$> ZipConduit (manyYield' atomLink .| headC)+    <*> ZipConduit parseRssChannelExtension+  parseRssItemExtension    = getZipConduit $ AtomItem+    <$> ZipConduit (manyYield' atomLink .| headC)+    <*> ZipConduit parseRssItemExtension -instance SingI AtomModule where sing = SAtomModule+instance RenderRssExtension a => RenderRssExtension (AtomModule a) where+  renderRssChannelExtension AtomChannel{..} = do+    mapM_ renderAtomLink channelAtomLink+    renderRssChannelExtension channelAtomOther+  renderRssItemExtension AtomItem{..}   = do+    mapM_ renderAtomLink itemAtomLink+    renderRssItemExtension itemAtomOther -instance ParseRssExtension AtomModule where-  parseRssChannelExtension = AtomChannel <$> (manyYield' atomLink .| headC)-  parseRssItemExtension    = AtomItem <$> (manyYield' atomLink .| headC) -instance RenderRssExtension AtomModule where-  renderRssChannelExtension = mapM_ renderAtomLink . channelAtomLink-  renderRssItemExtension    = mapM_ renderAtomLink . itemAtomLink+data instance RssChannelExtension (AtomModule a) = AtomChannel+  { channelAtomLink :: Maybe AtomLink+  , channelAtomOther :: RssChannelExtension a+  } -data instance RssChannelExtension AtomModule = AtomChannel { channelAtomLink :: Maybe AtomLink }-  deriving(Eq, Generic, Show)-data instance RssItemExtension AtomModule = AtomItem { itemAtomLink :: Maybe AtomLink }-  deriving(Eq, Generic, Show)+deriving instance Eq (RssChannelExtension a) => Eq (RssChannelExtension (AtomModule a))+deriving instance Ord (RssChannelExtension a) => Ord (RssChannelExtension (AtomModule a))+--deriving instance Read (RssChannelExtension a) => Read (RssChannelExtension (AtomModule a))+deriving instance Show (RssChannelExtension a) => Show (RssChannelExtension (AtomModule a))+deriving instance Generic (RssChannelExtension a) => Generic (RssChannelExtension (AtomModule a))+++data instance RssItemExtension (AtomModule a) = AtomItem+  { itemAtomLink :: Maybe AtomLink+  , itemAtomOther :: RssItemExtension a+  }++deriving instance Eq (RssItemExtension a) => Eq (RssItemExtension (AtomModule a))+deriving instance Ord (RssItemExtension a) => Ord (RssItemExtension (AtomModule a))+--deriving instance Read (RssItemExtension a) => Read (RssItemExtension (AtomModule a))+deriving instance Show (RssItemExtension a) => Show (RssItemExtension (AtomModule a))+deriving instance Generic (RssItemExtension a) => Generic (RssItemExtension (AtomModule a))
src/Text/RSS/Extensions/Content.hs view
@@ -1,9 +1,10 @@-{-# LANGUAGE DataKinds         #-}-{-# LANGUAGE DeriveGeneric     #-}-{-# LANGUAGE KindSignatures    #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RankNTypes        #-}-{-# LANGUAGE TypeFamilies      #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE FlexibleContexts   #-}+{-# LANGUAGE FlexibleInstances  #-}+{-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE RankNTypes         #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeFamilies       #-} -- | __Content__ extension for RSS. -- Cf specification at <http://web.resource.org/rss/1.0/modules/content/>. --@@ -26,11 +27,10 @@ import           Text.RSS.Extensions import           Text.RSS.Types -import           Conduit                (ConduitT, Source, headDefC, (.|))+import           Conduit                (ConduitT, Source, ZipConduit (..), headDefC, (.|)) import           Control.Exception.Safe as Exception import           Control.Monad import           Data.Maybe-import           Data.Singletons import           Data.Text              (Text) import qualified Data.Text              as Text import           Data.XML.Types@@ -41,23 +41,39 @@ -- }}}  -- | __Content__ tag type.-data ContentModule :: *+newtype ContentModule a = ContentModule a -data instance Sing ContentModule = SContentModule+instance ParseRssExtension a => ParseRssExtension (ContentModule a) where+  parseRssChannelExtension = parseRssChannelExtension+  parseRssItemExtension    = getZipConduit $ ContentItem+    <$> ZipConduit (manyYield' contentEncoded .| headDefC mempty)+    <*> ZipConduit parseRssItemExtension -instance SingI ContentModule where sing = SContentModule+instance RenderRssExtension a => RenderRssExtension (ContentModule a) where+  renderRssChannelExtension = renderRssChannelExtension+  renderRssItemExtension (ContentItem e a) = do+    unless (Text.null e) $ renderContentEncoded e+    renderRssItemExtension a -instance ParseRssExtension ContentModule where-  parseRssChannelExtension = pure ContentChannel-  parseRssItemExtension    = ContentItem <$> (manyYield' contentEncoded .| headDefC mempty)+data instance RssChannelExtension (ContentModule a) = ContentChannel (RssChannelExtension a) -instance RenderRssExtension ContentModule where-  renderRssChannelExtension = const $ pure ()-  renderRssItemExtension (ContentItem e) = unless (Text.null e) $ renderContentEncoded e+deriving instance Eq (RssChannelExtension a) => Eq (RssChannelExtension (ContentModule a))+deriving instance Ord (RssChannelExtension a) => Ord (RssChannelExtension (ContentModule a))+deriving instance Read (RssChannelExtension a) => Read (RssChannelExtension (ContentModule a))+deriving instance Show (RssChannelExtension a) => Show (RssChannelExtension (ContentModule a))+deriving instance Generic (RssChannelExtension a) => Generic (RssChannelExtension (ContentModule a)) -data instance RssChannelExtension ContentModule = ContentChannel deriving(Eq, Generic, Ord, Show)-data instance RssItemExtension ContentModule = ContentItem { itemContent :: Text }-  deriving(Eq, Generic, Ord, Show)+data instance RssItemExtension (ContentModule a) = ContentItem+  { itemContent :: Text+  , itemOther   :: RssItemExtension a+  }++deriving instance Eq (RssItemExtension a) => Eq (RssItemExtension (ContentModule a))+deriving instance Ord (RssItemExtension a) => Ord (RssItemExtension (ContentModule a))+deriving instance Read (RssItemExtension a) => Read (RssItemExtension (ContentModule a))+deriving instance Show (RssItemExtension a) => Show (RssItemExtension (ContentModule a))+deriving instance Generic (RssItemExtension a) => Generic (RssItemExtension (ContentModule a))+   -- | XML prefix is @content@.
src/Text/RSS/Extensions/DublinCore.hs view
@@ -1,11 +1,12 @@-{-# LANGUAGE DataKinds         #-}-{-# LANGUAGE DeriveGeneric     #-}-{-# LANGUAGE KindSignatures    #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RankNTypes        #-}-{-# LANGUAGE RecordWildCards   #-}-{-# LANGUAGE TemplateHaskell   #-}-{-# LANGUAGE TypeFamilies      #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE FlexibleContexts   #-}+{-# LANGUAGE FlexibleInstances  #-}+{-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE RankNTypes         #-}+{-# LANGUAGE RecordWildCards    #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell    #-}+{-# LANGUAGE TypeFamilies       #-} -- | __Dublin Core__ extension for RSS. --  Cf specification at <http://web.resource.org/rss/1.0/modules/dc/>. module Text.RSS.Extensions.DublinCore@@ -27,7 +28,6 @@ import           Control.Monad import           Control.Monad.Fix import           Data.Maybe-import           Data.Singletons import           Data.Text                          (Text) import qualified Data.Text                          as Text import           Data.Time.Clock@@ -69,7 +69,7 @@   , elementSubject     :: Text   , elementTitle       :: Text   , elementType        :: Text-  } deriving(Eq, Generic, Ord, Show)+  } deriving(Eq, Generic, Ord, Read, Show)  -- | Construct an empty 'DcMetaData'. mkDcMetaData = DcMetaData mempty mempty mempty Nothing mempty mempty mempty mempty mempty mempty mempty mempty mempty mempty mempty@@ -140,22 +140,43 @@   -- | __Dublin Core__ tag type.-data DublinCoreModule :: *+newtype DublinCoreModule a = DublinCoreModule a -data instance Sing DublinCoreModule = SDublinCoreModule+instance ParseRssExtension a => ParseRssExtension (DublinCoreModule a) where+  parseRssChannelExtension = getZipConduit $ DublinCoreChannel+    <$> ZipConduit dcMetadata+    <*> ZipConduit parseRssChannelExtension+  parseRssItemExtension    = getZipConduit $ DublinCoreItem+    <$> ZipConduit dcMetadata+    <*> ZipConduit parseRssItemExtension -instance SingI DublinCoreModule where sing = SDublinCoreModule+instance RenderRssExtension a => RenderRssExtension (DublinCoreModule a) where+  renderRssChannelExtension DublinCoreChannel{..} = do+    renderDcMetadata channelDcMetaData+    renderRssChannelExtension channelDcOther+  renderRssItemExtension DublinCoreItem{..}   = do+    renderDcMetadata itemDcMetaData+    renderRssItemExtension itemDcOther -instance ParseRssExtension DublinCoreModule where-  parseRssChannelExtension = DublinCoreChannel <$> dcMetadata-  parseRssItemExtension    = DublinCoreItem <$> dcMetadata -instance RenderRssExtension DublinCoreModule where-  renderRssChannelExtension = renderDcMetadata . channelDcMetaData-  renderRssItemExtension    = renderDcMetadata . itemDcMetaData+data instance RssChannelExtension (DublinCoreModule a) = DublinCoreChannel+  { channelDcMetaData :: DcMetaData+  , channelDcOther    :: RssChannelExtension a+  } +deriving instance Eq (RssChannelExtension a) => Eq (RssChannelExtension (DublinCoreModule a))+deriving instance Ord (RssChannelExtension a) => Ord (RssChannelExtension (DublinCoreModule a))+deriving instance Read (RssChannelExtension a) => Read (RssChannelExtension (DublinCoreModule a))+deriving instance Show (RssChannelExtension a) => Show (RssChannelExtension (DublinCoreModule a))+deriving instance Generic (RssChannelExtension a) => Generic (RssChannelExtension (DublinCoreModule a)) -data instance RssChannelExtension DublinCoreModule = DublinCoreChannel { channelDcMetaData :: DcMetaData }-  deriving(Eq, Generic, Ord, Show)-data instance RssItemExtension DublinCoreModule = DublinCoreItem { itemDcMetaData :: DcMetaData }-  deriving(Eq, Generic, Ord, Show)+data instance RssItemExtension (DublinCoreModule a) = DublinCoreItem+  { itemDcMetaData :: DcMetaData+  , itemDcOther    :: RssItemExtension a+  }++deriving instance Eq (RssItemExtension a) => Eq (RssItemExtension (DublinCoreModule a))+deriving instance Ord (RssItemExtension a) => Ord (RssItemExtension (DublinCoreModule a))+deriving instance Read (RssItemExtension a) => Read (RssItemExtension (DublinCoreModule a))+deriving instance Show (RssItemExtension a) => Show (RssItemExtension (DublinCoreModule a))+deriving instance Generic (RssItemExtension a) => Generic (RssItemExtension (DublinCoreModule a))
src/Text/RSS/Extensions/Syndication.hs view
@@ -1,11 +1,12 @@-{-# LANGUAGE DataKinds         #-}-{-# LANGUAGE DeriveGeneric     #-}-{-# LANGUAGE KindSignatures    #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RankNTypes        #-}-{-# LANGUAGE RecordWildCards   #-}-{-# LANGUAGE TemplateHaskell   #-}-{-# LANGUAGE TypeFamilies      #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE FlexibleContexts   #-}+{-# LANGUAGE FlexibleInstances  #-}+{-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE RankNTypes         #-}+{-# LANGUAGE RecordWildCards    #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell    #-}+{-# LANGUAGE TypeFamilies       #-} -- | __Syndication__ module for RSS. -- Cf specification at <http://web.resource.org/rss/1.0/modules/syndication/>. module Text.RSS.Extensions.Syndication@@ -42,7 +43,6 @@ import           Control.Monad import           Control.Monad.Fix import           Data.Maybe-import           Data.Singletons import           Data.Text import           Data.Time.Clock import           Data.Time.LocalTime@@ -181,21 +181,36 @@   -- | __Syndication__ tag type.-data SyndicationModule :: *+newtype SyndicationModule a = SyndicationModule a -data instance Sing SyndicationModule = SSyndicationModule+instance ParseRssExtension a => ParseRssExtension (SyndicationModule a) where+  parseRssChannelExtension = getZipConduit $ SyndicationChannel+    <$> ZipConduit syndicationInfo+    <*> ZipConduit parseRssChannelExtension+  parseRssItemExtension    = SyndicationItem <$> parseRssItemExtension -instance SingI SyndicationModule where sing = SSyndicationModule+instance RenderRssExtension a => RenderRssExtension (SyndicationModule a) where+  renderRssChannelExtension SyndicationChannel{..} = do+    renderSyndicationInfo channelSyndicationInfo+    renderRssChannelExtension channelSyndicationOther+  renderRssItemExtension (SyndicationItem a) = renderRssItemExtension a -instance ParseRssExtension SyndicationModule where-  parseRssChannelExtension = SyndicationChannel <$> syndicationInfo-  parseRssItemExtension    = pure SyndicationItem -instance RenderRssExtension SyndicationModule where-  renderRssChannelExtension = renderSyndicationInfo . channelSyndicationInfo-  renderRssItemExtension    = const $ pure ()+data instance RssChannelExtension (SyndicationModule a) = SyndicationChannel+  { channelSyndicationInfo  :: SyndicationInfo+  , channelSyndicationOther :: RssChannelExtension a+  } +deriving instance Eq (RssChannelExtension a) => Eq (RssChannelExtension (SyndicationModule a))+deriving instance Ord (RssChannelExtension a) => Ord (RssChannelExtension (SyndicationModule a))+deriving instance Read (RssChannelExtension a) => Read (RssChannelExtension (SyndicationModule a))+deriving instance Show (RssChannelExtension a) => Show (RssChannelExtension (SyndicationModule a))+deriving instance Generic (RssChannelExtension a) => Generic (RssChannelExtension (SyndicationModule a)) -data instance RssChannelExtension SyndicationModule = SyndicationChannel { channelSyndicationInfo :: SyndicationInfo}-  deriving (Eq, Generic, Ord, Read, Show)-data instance RssItemExtension SyndicationModule = SyndicationItem deriving (Eq, Generic, Ord, Read, Show)+data instance RssItemExtension (SyndicationModule a) = SyndicationItem (RssItemExtension a)++deriving instance Eq (RssItemExtension a) => Eq (RssItemExtension (SyndicationModule a))+deriving instance Ord (RssItemExtension a) => Ord (RssItemExtension (SyndicationModule a))+deriving instance Read (RssItemExtension a) => Read (RssItemExtension (SyndicationModule a))+deriving instance Show (RssItemExtension a) => Show (RssItemExtension (SyndicationModule a))+deriving instance Generic (RssItemExtension a) => Generic (RssItemExtension (SyndicationModule a))
src/Text/RSS/Lens.hs view
@@ -5,8 +5,6 @@ -- {{{ Imports import           Text.RSS.Types -import           Data.Vinyl.Lens-import           Data.Vinyl.TypeLevel import           Lens.Simple import           URI.ByteString -- }}}@@ -31,10 +29,6 @@ itemEnclosureL inj a@RssItem { itemEnclosure = e } = (\x -> a { itemEnclosure = e }) <$> traverse inj e {-# INLINE itemEnclosureL #-} -itemExtensionL :: RElem a e (RIndex a e) => Lens' (RssItem e) (RssItemExtension a)-itemExtensionL = itemExtensionsL . f . rlens where-  f inj (RssItemExtensions a) = RssItemExtensions <$> inj a-{-# INLINE itemExtensionL #-}  $(makeLensesBy (\n -> Just (n ++ "L")) ''RssTextInput) $(makeLensesBy (\n -> Just (n ++ "L")) ''RssCloud)@@ -53,8 +47,3 @@ channelCategoriesL :: Traversal' (RssDocument e) RssCategory channelCategoriesL inj a@RssDocument { channelCategories = c } = (\x -> a { channelCategories = c }) <$> traverse inj c {-# INLINE channelCategoriesL #-}--channelExtensionL :: RElem a e (RIndex a e) => Lens' (RssDocument e) (RssChannelExtension a)-channelExtensionL = channelExtensionsL . f . rlens where-  f inj (RssChannelExtensions a) = RssChannelExtensions <$> inj a-{-# INLINE channelExtensionL #-}
src/Text/RSS/Types.hs view
@@ -42,13 +42,11 @@ import           Control.Exception.Safe import           Data.Semigroup import           Data.Set-import           Data.Singletons.Prelude.List-import           Data.Text                    (Text, unpack)+import           Data.Text              (Text, unpack) import           Data.Time.Clock-import           Data.Time.LocalTime          ()+import           Data.Time.LocalTime    () import           Data.Version-import           Data.Vinyl.Core-import           GHC.Generics                 hiding ((:+:))+import           GHC.Generics           hiding ((:+:)) import           Text.Read import           URI.ByteString -- }}}@@ -148,7 +146,7 @@ -- | The @\<item\>@ element. -- -- This type is open to extensions.-data RssItem (extensions :: [*]) = RssItem+data RssItem extensions = RssItem   { itemTitle       :: Text   , itemLink        :: Maybe RssURI   , itemDescription :: Text@@ -159,16 +157,16 @@   , itemGuid        :: Maybe RssGuid   , itemPubDate     :: Maybe UTCTime   , itemSource      :: Maybe RssSource-  , itemExtensions  :: RssItemExtensions extensions+  , itemExtensions  :: RssItemExtension extensions   } -deriving instance (Eq (RssItemExtensions e)) => Eq (RssItem e)-deriving instance (Generic (RssItemExtensions e)) => Generic (RssItem e)-deriving instance (Ord (RssItemExtensions e)) => Ord (RssItem e)-deriving instance (Show (RssItemExtensions e)) => Show (RssItem e)+deriving instance (Eq (RssItemExtension e)) => Eq (RssItem e)+deriving instance (Generic (RssItemExtension e)) => Generic (RssItem e)+deriving instance (Ord (RssItemExtension e)) => Ord (RssItem e)+deriving instance (Show (RssItemExtension e)) => Show (RssItem e)  -- | Alias for 'RssItem' with no RSS extensions.-type RssItem' = RssItem '[]+type RssItem' = RssItem NoExtensions  -- | The @\<textInput\>@ element. data RssTextInput = RssTextInput@@ -242,7 +240,7 @@ -- | The @\<rss\>@ element. -- -- This type is open to extensions.-data RssDocument (extensions :: [*]) = RssDocument+data RssDocument extensions = RssDocument   { documentVersion       :: Version   , channelTitle          :: Text   , channelLink           :: RssURI@@ -264,32 +262,18 @@   , channelTextInput      :: Maybe RssTextInput   , channelSkipHours      :: Set Hour   , channelSkipDays       :: Set Day-  , channelExtensions     :: RssChannelExtensions extensions+  , channelExtensions     :: RssChannelExtension extensions   } -deriving instance (Eq (RssChannelExtensions e), Eq (RssItemExtensions e)) => Eq (RssDocument e)-deriving instance (Generic (RssChannelExtensions e), Generic (RssItemExtensions e)) => Generic (RssDocument e)-deriving instance (Ord (RssChannelExtensions e), Ord (RssItemExtensions e)) => Ord (RssDocument e)-deriving instance (Show (RssChannelExtensions e), Show (RssItemExtensions e)) => Show (RssDocument e)+deriving instance (Eq (RssChannelExtension e), Eq (RssItemExtension e)) => Eq (RssDocument e)+deriving instance (Generic (RssChannelExtension e), Generic (RssItemExtension e)) => Generic (RssDocument e)+deriving instance (Ord (RssChannelExtension e), Ord (RssItemExtension e)) => Ord (RssDocument e)+deriving instance (Show (RssChannelExtension e), Show (RssItemExtension e)) => Show (RssDocument e)  -- | Alias for 'RssDocument' with no RSS extensions.-type RssDocument' = RssDocument '[]+type RssDocument' = RssDocument NoExtensions  -- * RSS extensions------ $doc--- To implement an RSS extension:------ - Create a void data-type, that will be used as a tag to identify the extension:------   > data MyExtension :: *------ - Implement extension types for @\<channel\>@ and @\<item\>@ elements:------   > data instance RssChannelExtension MyExtension = MyExtensionChannel { {- ... fields -} }---   > data instance RssItemExtension MyExtension = MyExtensionItem { {- ... fields -} }------ - Implement corresponding parsers (cf "Text.RSS.Extensions").  -- | @\<channel\>@ extension type. data family RssChannelExtension extensionTag :: *@@ -297,22 +281,11 @@ -- | @\<item\>@ extension type. data family RssItemExtension extensionTag :: * --- | Combination of multiple @\<channel\>@ extensions.-data family RssChannelExtensions (extensionTags :: [*]) :: *-data instance RssChannelExtensions a = RssChannelExtensions { rssChannelExtension :: Rec RssChannelExtension a }--deriving instance (Eq (Rec RssChannelExtension a)) => Eq (RssChannelExtensions a)-deriving instance (Generic (Rec RssChannelExtension a)) => Generic (RssChannelExtensions a)-deriving instance (Ord (Rec RssChannelExtension a)) => Ord (RssChannelExtensions a)-deriving instance (Read (Rec RssChannelExtension a)) => Read (RssChannelExtensions a)-deriving instance (Show (Rec RssChannelExtension a)) => Show (RssChannelExtensions a)---- | Combination of multiple @\<item\>@ extensions.-data family RssItemExtensions (extensionTags :: [*]) :: *-data instance RssItemExtensions (a :: [*]) = RssItemExtensions { rssItemExtension :: Rec RssItemExtension a }+-- | Trivial extension type that parses/renders nothing.+data NoExtensions = NoExtensions+  deriving(Eq, Generic, Ord, Read, Show) -deriving instance (Eq (Rec RssItemExtension a)) => Eq (RssItemExtensions a)-deriving instance (Generic (Rec RssItemExtension a)) => Generic (RssItemExtensions a)-deriving instance (Ord (Rec RssItemExtension a)) => Ord (RssItemExtensions a)-deriving instance (Read (Rec RssItemExtension a)) => Read (RssItemExtensions a)-deriving instance (Show (Rec RssItemExtension a)) => Show (RssItemExtensions a)+data instance RssChannelExtension NoExtensions = NoChannelExtensions+  deriving(Eq, Generic, Ord, Read, Show)+data instance RssItemExtension NoExtensions = NoItemExtensions+  deriving(Eq, Generic, Ord, Read, Show)
src/Text/RSS1/Conduit/Parse.hs view
@@ -19,20 +19,18 @@ import           Text.RSS.Extensions import           Text.RSS.Types -import           Conduit                 hiding (throwM)-import           Control.Exception.Safe  as Exception+import           Conduit                hiding (throwM)+import           Control.Exception.Safe as Exception import           Control.Monad import           Control.Monad.Fix import           Data.Conduit import           Data.List.NonEmpty-import           Data.Singletons.Prelude-import           Data.Text               as Text+import           Data.Text              as Text import           Data.Text.Encoding import           Data.Time.Clock import           Data.Time.LocalTime import           Data.Time.RFC3339 import           Data.Version-import           Data.Vinyl.Core import           Data.XML.Types import           Lens.Simple import           Text.XML.Stream.Parse@@ -121,7 +119,7 @@ -- | Parse an @\<item\>@ element. -- -- RSS extensions are automatically parsed based on the inferred result type.-rss1Item :: ParseRssExtensions e => MonadCatch m => ConduitM Event o m (Maybe (RssItem e))+rss1Item :: ParseRssExtension e => MonadCatch m => ConduitM Event o m (Maybe (RssItem e)) rss1Item = rss1Tag "item" attributes $ \uri -> (manyYield' (choose piece) .| parser uri) <* many ignoreAnyTreeContent where   parser uri = getZipConduit $ RssItem     <$> ZipConduit (projectC _ItemTitle .| headDefC mempty)@@ -134,7 +132,7 @@     <*> pure mzero     <*> ZipConduit (projectC _ItemDate .| headC)     <*> pure mzero-    <*> ZipConduit (projectC _ItemOther .| concatC .| parseRssItemExtensions)+    <*> ZipConduit (projectC _ItemOther .| concatC .| parseRssItemExtension)   piece = [ fmap ItemTitle <$> rss1Tag "title" ignoreAttrs (const content)           , fmap ItemLink <$> rss1Tag "link" ignoreAttrs (const $ content >>= asRssURI)           , fmap ItemDescription <$> (rss1Tag "description" ignoreAttrs (const content) `orE` contentTag "encoded" ignoreAttrs (const content))@@ -172,7 +170,7 @@   attributes = requireAttr (rdfName "resource") <* ignoreAttrs  -data Rss1Channel (extensions :: [*]) = Rss1Channel+data Rss1Channel extensions = Rss1Channel   { channelId'          :: RssURI   , channelTitle'       :: Text   , channelLink'        :: RssURI@@ -180,7 +178,7 @@   , channelItems'       :: [Text]   , channelImage'       :: Maybe RssImage   , channelTextInput'   :: Maybe RssURI-  , channelExtensions'  :: RssChannelExtensions extensions+  , channelExtensions'  :: RssChannelExtension extensions   }  data ChannelPiece = ChannelTitle Text@@ -197,7 +195,7 @@ -- | Parse a @\<channel\>@ element. -- -- RSS extensions are automatically parsed based on the inferred result type.-rss1Channel :: ParseRssExtensions e => MonadThrow m => ConduitM Event o m (Maybe (Rss1Channel e))+rss1Channel :: ParseRssExtension e => MonadThrow m => ConduitM Event o m (Maybe (Rss1Channel e)) rss1Channel = rss1Tag "channel" attributes $ \channelId -> (manyYield' (choose piece) .| parser channelId) <* many ignoreAnyTreeContent where   parser channelId = getZipConduit $ Rss1Channel channelId     <$> ZipConduit (projectC _ChannelTitle .| headRequiredC "Missing <title> element")@@ -206,7 +204,7 @@     <*> ZipConduit (projectC _ChannelItems .| concatC .| sinkList)     <*> ZipConduit (projectC _ChannelImage .| headC)     <*> ZipConduit (projectC _ChannelTextInput .| headC)-    <*> ZipConduit (projectC _ChannelOther .| concatC .| parseRssChannelExtensions)+    <*> ZipConduit (projectC _ChannelOther .| concatC .| parseRssChannelExtension)   piece = [ fmap ChannelTitle <$> rss1Tag "title" ignoreAttrs (const content)           , fmap ChannelLink <$> rss1Tag "link" ignoreAttrs (const $ content >>= asRssURI)           , fmap ChannelDescription <$> rss1Tag "description" ignoreAttrs (const content)@@ -218,7 +216,7 @@   attributes = (requireAttr (rdfName "about") >>= asRssURI) <* ignoreAttrs  -data Rss1Document (e :: [*]) = Rss1Document (Rss1Channel e) (Maybe RssImage) [RssItem e] (Maybe RssTextInput)+data Rss1Document e = Rss1Document (Rss1Channel e) (Maybe RssImage) [RssItem e] (Maybe RssTextInput)  rss1ToRss2 :: Rss1Document e -> RssDocument e rss1ToRss2 (Rss1Document channel image items textInput) = RssDocument@@ -245,7 +243,7 @@   mempty   (channelExtensions' channel) -data DocumentPiece (e :: [*]) = DocumentChannel (Rss1Channel e)+data DocumentPiece e = DocumentChannel (Rss1Channel e)   | DocumentImage RssImage   | DocumentItem (RssItem e)   | DocumentTextInput RssTextInput@@ -256,7 +254,7 @@ -- | Parse an @\<RDF\>@ element. -- -- RSS extensions are automatically parsed based on the inferred result type.-rss1Document :: ParseRssExtensions e => MonadCatch m => ConduitM Event o m (Maybe (RssDocument e))+rss1Document :: ParseRssExtension e => MonadCatch m => ConduitM Event o m (Maybe (RssDocument e)) rss1Document = fmap (fmap rss1ToRss2) $ rdfTag "RDF" ignoreAttrs $ const $ (manyYield' (choose piece) .| parser) <* many ignoreAnyTreeContent where   parser = getZipConduit $ Rss1Document     <$> ZipConduit (projectC _DocumentChannel .| headRequiredC "Missing <channel> element")
test/Arbitrary.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE DataKinds         #-}+{-# LANGUAGE FlexibleContexts  #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs             #-} -- | 'Arbitrary' instances used by RSS types.@@ -14,14 +15,10 @@ import           Data.ByteString                 (ByteString) import           Data.Char import           Data.Maybe-import           Data.MonoTraversable            (Element)-import           Data.NonNull-import           Data.Sequences                  (SemiSequence) import           Data.Text                       (Text, find, pack) import           Data.Text.Encoding import           Data.Time.Clock import           Data.Version-import           Data.Vinyl.Core import           GHC.Generics import           Test.QuickCheck import           Test.QuickCheck.Instances       ()@@ -99,7 +96,7 @@ instance Arbitrary RssImage where   arbitrary = RssImage <$> arbitrary <*> (pack <$> listOf genAlphaNum) <*> arbitrary <*> fmap (fmap abs) arbitrary <*> fmap (fmap abs) arbitrary <*> (pack <$> listOf genAlphaNum) -instance Arbitrary (RssItem '[]) where+instance Arbitrary (RssItem NoExtensions) where   arbitrary = RssItem     <$> (pack <$> listOf genAlphaNum)     <*> arbitrary@@ -111,7 +108,7 @@     <*> arbitrary     <*> oneof [Just <$> genTime, pure Nothing]     <*> arbitrary-    <*> pure (RssItemExtensions RNil)+    <*> pure NoItemExtensions  instance Arbitrary RssSource where   arbitrary = RssSource <$> arbitrary <*> (pack <$> listOf genAlphaNum)@@ -119,7 +116,7 @@ instance Arbitrary RssTextInput where   arbitrary = RssTextInput <$> (pack <$> listOf genAlphaNum) <*> (pack <$> listOf genAlphaNum) <*> (pack <$> listOf genAlphaNum) <*> arbitrary -instance Arbitrary (RssDocument '[]) where+instance Arbitrary (RssDocument NoExtensions) where   arbitrary = RssDocument     <$> arbitrary     <*> arbitrary@@ -142,7 +139,7 @@     <*> arbitrary     <*> arbitrary     <*> arbitrary-    <*> pure (RssChannelExtensions RNil)+    <*> pure NoChannelExtensions  instance Arbitrary Day where   arbitrary = arbitraryBoundedEnum@@ -166,6 +163,12 @@   shrink (RssURI a@URI{})         = RssURI <$> shrink a   shrink (RssURI a@RelativeRef{}) = RssURI <$> shrink a +instance Arbitrary (RssChannelExtension NoExtensions) where+  arbitrary = pure NoChannelExtensions++instance Arbitrary (RssItemExtension NoExtensions) where+  arbitrary = pure NoItemExtensions+ instance Arbitrary DcMetaData where   arbitrary = DcMetaData     <$> arbitrary@@ -184,8 +187,8 @@     <*> arbitrary     <*> arbitrary -instance Arbitrary (RssChannelExtension DublinCoreModule) where-  arbitrary = DublinCoreChannel <$> arbitrary+instance Arbitrary (RssChannelExtension a) => Arbitrary (RssChannelExtension (DublinCoreModule a)) where+  arbitrary = DublinCoreChannel <$> arbitrary <*> arbitrary  instance Arbitrary SyndicationPeriod where   arbitrary = arbitraryBoundedEnum@@ -197,8 +200,8 @@     <*> arbitrary     <*> oneof [Just <$> genTime, pure Nothing] -instance Arbitrary (RssChannelExtension SyndicationModule) where-  arbitrary = SyndicationChannel <$> arbitrary+instance Arbitrary (RssChannelExtension a) => Arbitrary (RssChannelExtension (SyndicationModule a)) where+  arbitrary = SyndicationChannel <$> arbitrary <*> arbitrary  instance Arbitrary AtomURI where   arbitrary = oneof [AtomURI <$> (arbitrary :: Gen (URIRef Absolute)), AtomURI <$> (arbitrary :: Gen (URIRef Relative))]@@ -206,8 +209,8 @@ instance Arbitrary AtomLink where   arbitrary = AtomLink <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary -instance Arbitrary (RssChannelExtension AtomModule) where-  arbitrary = AtomChannel <$> arbitrary+instance Arbitrary (RssChannelExtension a) => Arbitrary (RssChannelExtension (AtomModule a)) where+  arbitrary = AtomChannel <$> arbitrary <*> arbitrary -instance Arbitrary (RssItemExtension ContentModule) where-  arbitrary = ContentItem <$> arbitrary+instance Arbitrary (RssItemExtension a) => Arbitrary (RssItemExtension (ContentModule a)) where+  arbitrary = ContentItem <$> arbitrary <*> arbitrary
test/Main.hs view
@@ -4,7 +4,6 @@ {-# LANGUAGE OverloadedStrings   #-} {-# LANGUAGE QuasiQuotes         #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeApplications    #-} -- {{{ Imports import           Text.RSS.Conduit.Parse          as Parser import           Text.RSS.Conduit.Render         as Renderer@@ -17,8 +16,6 @@ import           Text.RSS.Types import           Text.RSS1.Conduit.Parse         as Parser -import           Arbitrary-import           Blaze.ByteString.Builder        (toByteString) import           Conduit import           Control.Exception.Safe          as Exception import           Control.Monad@@ -28,15 +25,11 @@ import           Data.Conduit.List import           Data.Default import           Data.Maybe-import           Data.Singletons.Prelude.List import           Data.String-import           Data.Text                       (Text)-import           Data.Text.Encoding-import qualified Data.Text.Lazy.Encoding      as Lazy-import           Data.Time.Calendar+import qualified Data.Text.Lazy.Encoding         as Lazy+import           Data.Time.Calendar              hiding (DayOfWeek (..)) import           Data.Time.LocalTime import           Data.Version-import           Data.Vinyl.Core import           Data.Void import           Data.XML.Types import           Lens.Simple@@ -44,9 +37,8 @@ import           System.IO import           System.Timeout import           Test.Tasty-import           Test.Tasty.Golden            (findByExtension, goldenVsString)+import           Test.Tasty.Golden               (findByExtension, goldenVsString) import           Test.Tasty.HUnit-import           Test.Tasty.QuickCheck import           Text.Atom.Conduit.Parse import           Text.Atom.Types import           Text.XML.Stream.Parse           as XML hiding (choose)@@ -61,7 +53,6 @@   defaultMain $ testGroup "Tests"     [ unitTests     , goldenTests-    , properties     ]  unitTests :: TestTree@@ -98,45 +89,11 @@     xmlFile <- xmlFiles     let goldenFile = addExtension xmlFile ".golden"         f file = fmap (Lazy.encodeUtf8 . fromString . show) $ runResourceT $ runConduit $ sourceFile file .| Conduit.decodeUtf8C .| XML.parseText' def .| parser-        parser = rssDocument :: MonadThrow m => ConduitM Event o m (Maybe (RssDocument '[]))+        parser = rssDocument :: MonadThrow m => ConduitM Event o m (Maybe (RssDocument NoExtensions))      return $ goldenVsString xmlFile goldenFile $ f xmlFile -properties :: TestTree-properties = testGroup "Properties"-  [ roundtripProperty "RssTextInput" renderRssTextInput rssTextInput-  , roundtripProperty "RssImage" renderRssImage rssImage-  , roundtripProperty "RssCategory" renderRssCategory rssCategory-  , roundtripProperty "RssEnclosure" renderRssEnclosure rssEnclosure-  , roundtripProperty "RssSource" renderRssSource rssSource-  , roundtripProperty "RssGuid" renderRssGuid rssGuid-  , roundtripProperty "RssItem"-      (renderRssItem :: RssItem '[] -> ConduitT () Event Maybe ())-      rssItem-  , roundtripProperty "DublinCore"-      (renderRssChannelExtension @DublinCoreModule)-      (Just <$> parseRssChannelExtension)-  , roundtripProperty "Syndication"-      (renderRssChannelExtension @SyndicationModule)-      (Just <$> parseRssChannelExtension)-  , roundtripProperty "Atom"-      (renderRssChannelExtension @AtomModule)-      (Just <$> parseRssChannelExtension)-  , roundtripProperty "Content"-      (renderRssItemExtension @ContentModule)-      (Just <$> parseRssItemExtension)-  ] --roundtripProperty :: Eq a => Arbitrary a => Show a-                  => TestName -> (a -> ConduitT () Event Maybe ()) -> ConduitT Event Void Maybe (Maybe a) -> TestTree-roundtripProperty name render parse = testProperty ("parse . render = id (" <> name <> ")") $ do-  input <- arbitrary-  let intermediate = fmap (decodeUtf8 . toByteString) $ runConduit $ render input .| renderBuilder def .| foldC-      output = join $ runConduit $ render input .| parse-  return $ counterexample (show input <> " | " <> show intermediate <> " | " <> show output) $ Just input == output-- skipHoursCase :: TestTree skipHoursCase = testCase "<skipHours> element" $ do   result <- runResourceT . runConduit $ sourceList input .| XML.parseText' def .| force "ERROR" rssSkipHours@@ -279,7 +236,7 @@   result^.itemTitleL @?= "Processing Inclusions with XSLT"   result^.itemLinkL @?= Just link   result^.itemDescriptionL @?= "Processing document inclusions with general XML tools can be problematic. This article proposes a way of preserving inclusion information through SAX-based processing."-  result^.itemExtensionsL @?= RssItemExtensions RNil+  result^.itemExtensionsL @?= NoItemExtensions   where input = [ "<item xmlns=\"http://purl.org/rss/1.0/\""                 , "xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""                 , "xmlns:dc=\"http://purl.org/dc/elements/1.1/\""@@ -302,7 +259,7 @@   result^.itemLinkL @?= Just link   result^.itemDescriptionL @?= "Here is some text containing an interesting description."   result^.itemGuidL @?= Just (GuidText "7bd204c6-1655-4c27-aeee-53f933c5395f")-  result^.itemExtensionsL @?= RssItemExtensions RNil+  result^.itemExtensionsL @?= NoItemExtensions   isJust (result^.itemPubDateL) @?= True   where input = [ "<item>"                 , "<title>Example entry</title>"@@ -324,7 +281,7 @@   result^.itemDescriptionL @?= ""   result^.itemAuthorL @?= "author@w3schools.com"   result^.itemGuidL @?= Nothing-  result^.itemExtensionsL @?= RssItemExtensions RNil+  result^.itemExtensionsL @?= NoItemExtensions   isJust (result^.itemPubDateL) @?= True   where input = [ "<item>"                 , "<title>Plop</title>"@@ -364,7 +321,7 @@   result^?channelTextInputL._Just.textInputDescriptionL @?= Just "Search XML.com's XML collection"   result^?channelTextInputL._Just.textInputNameL @?= Just "s"   result^?channelTextInputL._Just.textInputLinkL @?= Just textInputLink-  result^.channelExtensionsL @?= RssChannelExtensions RNil+  result^.channelExtensionsL @?= NoChannelExtensions   where input = [ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"                 , "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns=\"http://purl.org/rss/1.0/\">"                 , "<channel rdf:about=\"http://www.xml.com/xml/news.rss\">"@@ -411,7 +368,7 @@ dublinCoreChannelCase :: TestTree dublinCoreChannelCase = testCase "Dublin Core <channel> extension" $ do   Just result <- runResourceT . runConduit $ sourceList input .| XML.parseText' def .| rssDocument-  result^.channelExtensionsL @?= RssChannelExtensions (DublinCoreChannel dublinCoreElement :& RNil)+  result^.channelExtensionsL @?= DublinCoreChannel dublinCoreElement NoChannelExtensions   where input = [ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"                 , "<rss xmlns:dc=\"http://purl.org/dc/elements/1.1/\" version=\"2.0\">"                 , "<channel>"@@ -439,7 +396,7 @@ dublinCoreItemCase :: TestTree dublinCoreItemCase = testCase "Dublin Core <item> extension" $ do   Just result <- runResourceT . runConduit $ sourceList input .| XML.parseText' def .| rssItem-  result^.itemExtensionsL @?= RssItemExtensions (DublinCoreItem dublinCoreElement :& RNil)+  result^.itemExtensionsL @?= DublinCoreItem dublinCoreElement NoItemExtensions   where input = [ "<item xmlns:dc=\"http://purl.org/dc/elements/1.1/\">"                 , "<title>Example entry</title>"                 , "<dc:description>XML is placing increasingly heavy loads on the existing technical "@@ -466,7 +423,7 @@ contentItemCase :: TestTree contentItemCase = testCase "Content <item> extension" $ do   Just result <- runResourceT . runConduit $ sourceList input .| XML.parseText' def .| rssItem-  result^.itemExtensionsL @?= RssItemExtensions (ContentItem "<p>What a <em>beautiful</em> day!</p>" :& RNil)+  result^.itemExtensionsL @?= ContentItem "<p>What a <em>beautiful</em> day!</p>" NoItemExtensions   where input = [ "<item xmlns:content=\"http://purl.org/rss/1.0/modules/content/\">"                 , "<title>Example entry</title>"                 , "<content:encoded><![CDATA[<p>What a <em>beautiful</em> day!</p>]]></content:encoded>"@@ -476,7 +433,7 @@ syndicationChannelCase :: TestTree syndicationChannelCase = testCase "Syndication <channel> extension" $ do   Just result <- runResourceT . runConduit $ sourceList input .| XML.parseText' def .| rssDocument-  result^.channelExtensionsL @?= RssChannelExtensions (SyndicationChannel syndicationInfo :& RNil)+  result^.channelExtensionsL @?= SyndicationChannel syndicationInfo NoChannelExtensions   where input = [ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"                 , "<rss xmlns:sy=\"http://purl.org/rss/1.0/modules/syndication/\" version=\"2.0\">"                 , "<channel>"@@ -498,7 +455,7 @@ atomChannelCase :: TestTree atomChannelCase = testCase "Atom <channel> extension" $ do   Just result <- runResourceT . runConduit $ sourceList input .| XML.parseText' def .| rssDocument-  result^.channelExtensionsL @?= RssChannelExtensions (AtomChannel (Just link) :& RNil)+  result^.channelExtensionsL @?= AtomChannel (Just link) NoChannelExtensions   where input = [ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"                 , "<rss xmlns:atom=\"http://www.w3.org/2005/Atom\" version=\"2.0\">"                 , "<channel>"@@ -514,7 +471,7 @@ multipleExtensionsCase :: TestTree multipleExtensionsCase = testCase "Multiple extensions" $ do   Just result <- runResourceT . runConduit $ sourceList input .| XML.parseText' def .| rssItem-  result^.itemExtensionsL @?= RssItemExtensions (ContentItem "<p>What a <em>beautiful</em> day!</p>" :& AtomItem (Just link) :& RNil)+  result^.itemExtensionsL @?= ContentItem "<p>What a <em>beautiful</em> day!</p>" (AtomItem (Just link) NoItemExtensions)   where input = [ "<item xmlns:content=\"http://purl.org/rss/1.0/modules/content/\""                 , " xmlns:atom=\"http://www.w3.org/2005/Atom\">"                 , "<title>Example entry</title>"@@ -524,30 +481,3 @@                 ]         url = AtomURI [uri|http://dallas.example.com/rss.xml|]         link = AtomLink url "self" "application/rss+xml" mempty mempty mempty---roundtripTextInputProperty :: TestTree-roundtripTextInputProperty = testProperty "parse . render = id (RssTextInput)" $ \t -> either (const False) (t ==) (runConduit $ renderRssTextInput t .| force "ERROR" rssTextInput)--roundtripImageProperty :: TestTree-roundtripImageProperty = testProperty "parse . render = id (RssImage)" $ \t -> either (const False) (t ==) (runConduit $ renderRssImage t .| force "ERROR" rssImage)--roundtripCategoryProperty :: TestTree-roundtripCategoryProperty = testProperty "parse . render = id (RssCategory)" $ \t -> either (const False) (t ==) (runConduit $ renderRssCategory t .| force "ERROR" rssCategory)--roundtripEnclosureProperty :: TestTree-roundtripEnclosureProperty = testProperty "parse . render = id (RssEnclosure)" $ \t -> either (const False) (t ==) (runConduit $ renderRssEnclosure t .| force "ERROR" rssEnclosure)--roundtripSourceProperty :: TestTree-roundtripSourceProperty = testProperty "parse . render = id (RssSource)" $ \t -> either (const False) (t ==) (runConduit $ renderRssSource t .| force "ERROR" rssSource)--roundtripGuidProperty :: TestTree-roundtripGuidProperty = testProperty "parse . render = id (RssGuid)" $ \t -> either (const False) (t ==) (runConduit $ renderRssGuid t .| force "ERROR" rssGuid)--roundtripItemProperty :: TestTree-roundtripItemProperty = testProperty "parse . render = id (RssItem)" $ \(t :: RssItem '[]) -> either (const False) (t ==) (runConduit $ renderRssItem t .| force "ERROR" rssItem)---letter = choose ('a', 'z')-digit = arbitrary `suchThat` isDigit-alphaNum = oneof [letter, digit]
+ test/QuickCheck.hs view
@@ -0,0 +1,104 @@+{-# LANGUAGE FlexibleContexts    #-}+{-# LANGUAGE FlexibleInstances   #-}+{-# LANGUAGE OverloadedLists     #-}+{-# LANGUAGE OverloadedStrings   #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications    #-}+-- {{{ Imports+import           Text.RSS.Conduit.Parse          as Parser+import           Text.RSS.Conduit.Render         as Renderer+import           Text.RSS.Extensions+import           Text.RSS.Extensions.Atom+import           Text.RSS.Extensions.Content+import           Text.RSS.Extensions.DublinCore+import           Text.RSS.Extensions.Syndication+import           Text.RSS.Lens+import           Text.RSS.Types+import           Text.RSS1.Conduit.Parse         as Parser++import           Arbitrary+import           Blaze.ByteString.Builder        (toByteString)+import           Conduit+import           Control.Monad+import           Data.Char+import           Data.Conduit+import           Data.Conduit.List+import           Data.Maybe+import           Data.String+import           Data.Text                       (Text)+import           Data.Text.Encoding+import qualified Data.Text.Lazy.Encoding         as Lazy+import           Data.Time.Calendar+import           Data.Time.LocalTime+import           Data.Version+import           Data.Void+import           Data.XML.Types+import           Prelude                         ()+import           Prelude.Compat+import           System.FilePath+import           System.IO+import           System.Timeout+import           Test.Tasty+import           Test.Tasty.QuickCheck+import           Text.Atom.Conduit.Parse+import           Text.Atom.Types+import           Text.XML.Stream.Parse           as XML hiding (choose)+import           Text.XML.Stream.Render+import           URI.ByteString+import           URI.ByteString.QQ+-- }}}++main :: IO ()+main = defaultMain $ testGroup "Property tests"+  [ roundtripProperty "RssTextInput" renderRssTextInput rssTextInput+  , roundtripProperty "RssImage" renderRssImage rssImage+  , roundtripProperty "RssCategory" renderRssCategory rssCategory+  , roundtripProperty "RssEnclosure" renderRssEnclosure rssEnclosure+  , roundtripProperty "RssSource" renderRssSource rssSource+  , roundtripProperty "RssGuid" renderRssGuid rssGuid+--   , roundtripProperty "RssItem"+--       (renderRssItem :: RssItem '[] -> ConduitT () Event Maybe ())+--       rssItem+  , roundtripProperty "DublinCore"+      (renderRssChannelExtension @(DublinCoreModule NoExtensions))+      (Just <$> parseRssChannelExtension)+  , roundtripProperty "Syndication"+      (renderRssChannelExtension @(SyndicationModule NoExtensions))+      (Just <$> parseRssChannelExtension)+  , roundtripProperty "Atom"+      (renderRssChannelExtension @(AtomModule NoExtensions))+      (Just <$> parseRssChannelExtension)+  , roundtripProperty "Content"+      (renderRssItemExtension @(ContentModule NoExtensions))+      (Just <$> parseRssItemExtension)+  ]+++roundtripProperty :: Eq a => Arbitrary a => Show a+                  => TestName -> (a -> ConduitT () Event Maybe ()) -> ConduitT Event Void Maybe (Maybe a) -> TestTree+roundtripProperty name render parse = testProperty ("parse . render = id (" <> name <> ")") $ do+  input <- arbitrary+  let intermediate = fmap (decodeUtf8 . toByteString) $ runConduit $ render input .| renderBuilder def .| foldC+      output = join $ runConduit $ render input .| parse+  return $ counterexample (show input <> " | " <> show intermediate <> " | " <> show output) $ Just input == output++roundtripTextInputProperty :: TestTree+roundtripTextInputProperty = testProperty "parse . render = id (RssTextInput)" $ \t -> either (const False) (t ==) (runConduit $ renderRssTextInput t .| force "ERROR" rssTextInput)++roundtripImageProperty :: TestTree+roundtripImageProperty = testProperty "parse . render = id (RssImage)" $ \t -> either (const False) (t ==) (runConduit $ renderRssImage t .| force "ERROR" rssImage)++roundtripCategoryProperty :: TestTree+roundtripCategoryProperty = testProperty "parse . render = id (RssCategory)" $ \t -> either (const False) (t ==) (runConduit $ renderRssCategory t .| force "ERROR" rssCategory)++roundtripEnclosureProperty :: TestTree+roundtripEnclosureProperty = testProperty "parse . render = id (RssEnclosure)" $ \t -> either (const False) (t ==) (runConduit $ renderRssEnclosure t .| force "ERROR" rssEnclosure)++roundtripSourceProperty :: TestTree+roundtripSourceProperty = testProperty "parse . render = id (RssSource)" $ \t -> either (const False) (t ==) (runConduit $ renderRssSource t .| force "ERROR" rssSource)++roundtripGuidProperty :: TestTree+roundtripGuidProperty = testProperty "parse . render = id (RssGuid)" $ \t -> either (const False) (t ==) (runConduit $ renderRssGuid t .| force "ERROR" rssGuid)++roundtripItemProperty :: TestTree+roundtripItemProperty = testProperty "parse . render = id (RssItem)" $ \(t :: RssItem NoExtensions) -> either (const False) (t ==) (runConduit $ renderRssItem t .| force "ERROR" rssItem)