    {-# OPTIONS -fno-warn-incomplete-patterns #-}

    --------------------------------------------------------------------
    -- |
    -- Module    : Text.Feed.Constructor
    -- Copyright : (c) Galois, Inc. 2008,
    --             (c) Sigbjorn Finne 2009-
    -- License   : BSD3
    --
    -- Maintainer: Sigbjorn Finne <sof@forkIO.com>
    -- Stability : provisional
    -- Description: Module for an abstraction layer between different kinds of feeds.
    --
    --------------------------------------------------------------------
    module Text.Feed.Constructor
      ( FeedKind(..)
      , newFeed -- :: FeedKind  -> Feed
      , feedFromRSS -- :: RSS       -> Feed
      , feedFromAtom -- :: Atom.Feed -> Feed
      , feedFromRDF -- :: RSS1.Feed -> Feed
      , feedFromXML -- :: Element   -> Feed
      , getFeedKind -- :: Feed      -> FeedKind
      , FeedSetter -- type _ a = a -> Feed -> Feed
      , addItem -- :: FeedSetter Item
      , withFeedTitle -- :: FeedSetter Text
      , withFeedHome -- :: FeedSetter URLString
      , withFeedHTML -- :: FeedSetter URLString
      , withFeedDescription -- :: FeedSetter Text
      , withFeedPubDate -- :: FeedSetter DateString
      , withFeedLastUpdate -- :: FeedSetter DateString
      , withFeedDate -- :: FeedSetter DateString
      , withFeedLogoLink -- :: FeedSetter URLString
      , withFeedLanguage -- :: FeedSetter Text
      , withFeedCategories -- :: FeedSetter [(Text, Maybe Text)]
      , withFeedGenerator -- :: FeedSetter Text
      , withFeedItems -- :: FeedSetter [Item]
      , newItem -- :: FeedKind   -> Item
      , getItemKind -- :: Item       -> FeedKind
      , atomEntryToItem -- :: Atom.Entry -> Item
      , rssItemToItem -- :: RSS.Item   -> Item
      , rdfItemToItem -- :: RSS1.Item  -> Item
      , ItemSetter -- type _ a = a -> Item -> Item
      , withItemTitle -- :: ItemSetter Text
      , withItemLink -- :: ItemSetter URLString
      , withItemPubDate -- :: ItemSetter DateString
      , withItemDate -- :: ItemSetter DateString
      , withItemAuthor -- :: ItemSetter Text
      , withItemCommentLink -- :: ItemSetter Text
      , withItemEnclosure -- :: Text -> Maybe Text -> ItemSetter Integer
      , withItemFeedLink -- :: Text -> ItemSetter Text
      , withItemId -- :: Bool   -> ItemSetter Text
      , withItemCategories -- :: ItemSetter [(Text, Maybe Text)]
      , withItemDescription -- :: ItemSetter Text
      , withItemRights -- :: ItemSetter Text
      ) where

    import Prelude.Compat

    import Text.Feed.Types as Feed.Types

    import Text.Atom.Feed as Atom
    import Text.DublinCore.Types
    import Text.RSS.Syntax as RSS
    import Text.RSS1.Syntax as RSS1

    import Data.XML.Compat
    import Data.XML.Types as XML

    import Data.Char (toLower)
    import Data.Maybe (fromMaybe, mapMaybe)
    import Data.Text (Text, pack)

    -- ToDo:
    --
    --  - complete set of constructors over feeds
    --  - provide a unified treatment of date string reps.
    --    (i.e., I know they differ across formats, but ignorant what
    --    the constraints are at the moment.)
    -- | Construct an empty feed document, intending to output it in
    -- the 'fk' feed format.
    newFeed :: FeedKind -> Feed.Types.Feed
    newFeed :: FeedKind -> Feed
    newFeed fk :: FeedKind
    fk =
      case FeedKind
    fk of
        AtomKind ->
          Feed -> Feed
    AtomFeed
            (URI -> TextContent -> URI -> Feed
    Atom.nullFeed
               "feed-id-not-filled-in"
               (URI -> TextContent
    TextString "dummy-title")
               "dummy-and-bogus-update-date")
        RSSKind mbV :: Maybe URI
    mbV ->
          let def :: RSS
    def = URI -> URI -> RSS
    RSS.nullRSS "dummy-title" "default-channel-url"
           in RSS -> Feed
    RSSFeed (RSS -> Feed) -> RSS -> Feed
    forall a b. (a -> b) -> a -> b
    $ RSS -> (URI -> RSS) -> Maybe URI -> RSS
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe RSS
    def (\v :: URI
    v -> RSS
    def {rssVersion :: URI
    RSS.rssVersion = URI
    v}) Maybe URI
    mbV
        RDFKind mbV :: Maybe URI
    mbV ->
          let def :: Feed
    def = URI -> URI -> Feed
    RSS1.nullFeed "default-channel-url" "dummy-title"
           in Feed -> Feed
    RSS1Feed (Feed -> Feed) -> Feed -> Feed
    forall a b. (a -> b) -> a -> b
    $ Feed -> (URI -> Feed) -> Maybe URI -> Feed
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Feed
    def (\v :: URI
    v -> Feed
    def {feedVersion :: URI
    RSS1.feedVersion = URI
    v}) Maybe URI
    mbV

    feedFromRSS :: RSS.RSS -> Feed.Types.Feed
    feedFromRSS :: RSS -> Feed
    feedFromRSS = RSS -> Feed
    RSSFeed

    feedFromAtom :: Atom.Feed -> Feed.Types.Feed
    feedFromAtom :: Feed -> Feed
    feedFromAtom = Feed -> Feed
    AtomFeed

    feedFromRDF :: RSS1.Feed -> Feed.Types.Feed
    feedFromRDF :: Feed -> Feed
    feedFromRDF = Feed -> Feed
    RSS1Feed

    feedFromXML :: XML.Element -> Feed.Types.Feed
    feedFromXML :: Element -> Feed
    feedFromXML = Element -> Feed
    XMLFeed

    getFeedKind :: Feed.Types.Feed -> FeedKind
    getFeedKind :: Feed -> FeedKind
    getFeedKind f :: Feed
    f =
      case Feed
    f of
        Feed.Types.AtomFeed {} -> FeedKind
    AtomKind
        Feed.Types.RSSFeed r :: RSS
    r ->
          Maybe URI -> FeedKind
    RSSKind
            (case RSS -> URI
    RSS.rssVersion RSS
    r of
               "2.0" -> Maybe URI
    forall a. Maybe a
    Nothing
               v :: URI
    v -> URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    v)
        Feed.Types.RSS1Feed r :: Feed
    r ->
          Maybe URI -> FeedKind
    RDFKind
            (case Feed -> URI
    RSS1.feedVersion Feed
    r of
               "1.0" -> Maybe URI
    forall a. Maybe a
    Nothing
               v :: URI
    v -> URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    v)
        Feed.Types.XMLFeed {} -> Maybe URI -> FeedKind
    RSSKind (URI -> Maybe URI
    forall a. a -> Maybe a
    Just "2.0") -- for now, just a hunch..

    addItem :: Feed.Types.Item -> Feed.Types.Feed -> Feed.Types.Feed
    addItem :: Item -> Feed -> Feed
    addItem it :: Item
    it f :: Feed
    f =
      case (Item
    it, Feed
    f) of
        (Feed.Types.AtomItem e :: Entry
    e, Feed.Types.AtomFeed fe :: Feed
    fe) ->
          Feed -> Feed
    Feed.Types.AtomFeed Feed
    fe {feedEntries :: [Entry]
    Atom.feedEntries = Entry
    e Entry -> [Entry] -> [Entry]
    forall a. a -> [a] -> [a]
    : Feed -> [Entry]
    Atom.feedEntries Feed
    fe}
        (Feed.Types.RSSItem e :: RSSItem
    e, Feed.Types.RSSFeed r :: RSS
    r) ->
          RSS -> Feed
    Feed.Types.RSSFeed
            RSS
    r {rssChannel :: RSSChannel
    RSS.rssChannel = (RSS -> RSSChannel
    RSS.rssChannel RSS
    r) {rssItems :: [RSSItem]
    RSS.rssItems = RSSItem
    e RSSItem -> [RSSItem] -> [RSSItem]
    forall a. a -> [a] -> [a]
    : RSSChannel -> [RSSItem]
    RSS.rssItems (RSS -> RSSChannel
    RSS.rssChannel RSS
    r)}}
        (Feed.Types.RSS1Item e :: Item
    e, Feed.Types.RSS1Feed r :: Feed
    r)
             -- note: do not update the channel item URIs at this point;
             -- will delay doing so until serialization.
         -> Feed -> Feed
    Feed.Types.RSS1Feed Feed
    r {feedItems :: [Item]
    RSS1.feedItems = Item
    e Item -> [Item] -> [Item]
    forall a. a -> [a] -> [a]
    : Feed -> [Item]
    RSS1.feedItems Feed
    r}
        _ ->
          [Char] -> Feed
    forall a. HasCallStack => [Char] -> a
    error "addItem: currently unable to automatically convert items from one feed type to another"

    withFeedItems :: FeedSetter [Feed.Types.Item]
    withFeedItems :: FeedSetter [Item]
    withFeedItems is :: [Item]
    is fe :: Feed
    fe =
      (Item -> Feed -> Feed) -> Feed -> [Item] -> Feed
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr
        Item -> Feed -> Feed
    addItem
        (case Feed
    fe of
           Feed.Types.AtomFeed f :: Feed
    f -> Feed -> Feed
    Feed.Types.AtomFeed Feed
    f {feedEntries :: [Entry]
    Atom.feedEntries = []}
           Feed.Types.RSSFeed f :: RSS
    f -> RSS -> Feed
    Feed.Types.RSSFeed RSS
    f {rssChannel :: RSSChannel
    rssChannel = (RSS -> RSSChannel
    rssChannel RSS
    f) {rssItems :: [RSSItem]
    rssItems = []}}
           Feed.Types.RSS1Feed f :: Feed
    f -> Feed -> Feed
    Feed.Types.RSS1Feed Feed
    f {feedItems :: [Item]
    feedItems = []})
        [Item]
    is

    newItem :: FeedKind -> Feed.Types.Item
    newItem :: FeedKind -> Item
    newItem fk :: FeedKind
    fk =
      case FeedKind
    fk of
        AtomKind ->
          Entry -> Item
    Feed.Types.AtomItem (Entry -> Item) -> Entry -> Item
    forall a b. (a -> b) -> a -> b
    $
          URI -> TextContent -> URI -> Entry
    Atom.nullEntry
            "entry-id-not-filled-in"
            (URI -> TextContent
    TextString "dummy-entry-title")
            "dummy-and-bogus-entry-update-date"
        RSSKind {} -> RSSItem -> Item
    Feed.Types.RSSItem (RSSItem -> Item) -> RSSItem -> Item
    forall a b. (a -> b) -> a -> b
    $ URI -> RSSItem
    RSS.nullItem "dummy-rss-item-title"
        RDFKind {} ->
          Item -> Item
    Feed.Types.RSS1Item (Item -> Item) -> Item -> Item
    forall a b. (a -> b) -> a -> b
    $ URI -> URI -> URI -> Item
    RSS1.nullItem "dummy-item-uri" "dummy-item-title" "dummy-item-link"

    getItemKind :: Feed.Types.Item -> FeedKind
    getItemKind :: Item -> FeedKind
    getItemKind f :: Item
    f =
      case Item
    f of
        Feed.Types.AtomItem {} -> FeedKind
    AtomKind
        Feed.Types.RSSItem {} -> Maybe URI -> FeedKind
    RSSKind (URI -> Maybe URI
    forall a. a -> Maybe a
    Just "2.0") -- good guess..
        Feed.Types.RSS1Item {} -> Maybe URI -> FeedKind
    RDFKind (URI -> Maybe URI
    forall a. a -> Maybe a
    Just "1.0")
        Feed.Types.XMLItem {} -> Maybe URI -> FeedKind
    RSSKind (URI -> Maybe URI
    forall a. a -> Maybe a
    Just "2.0")

    type FeedSetter a = a -> Feed.Types.Feed -> Feed.Types.Feed

    withFeedTitle :: FeedSetter Text
    withFeedTitle :: FeedSetter URI
    withFeedTitle tit :: URI
    tit fe :: Feed
    fe =
      case Feed
    fe of
        Feed.Types.AtomFeed f :: Feed
    f -> Feed -> Feed
    Feed.Types.AtomFeed Feed
    f {feedTitle :: TextContent
    feedTitle = URI -> TextContent
    TextString URI
    tit}
        Feed.Types.RSSFeed f :: RSS
    f -> RSS -> Feed
    Feed.Types.RSSFeed RSS
    f {rssChannel :: RSSChannel
    rssChannel = (RSS -> RSSChannel
    rssChannel RSS
    f) {rssTitle :: URI
    rssTitle = URI
    tit}}
        Feed.Types.RSS1Feed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.RSS1Feed Feed
    f {feedChannel :: Channel
    feedChannel = (Feed -> Channel
    feedChannel Feed
    f) {channelTitle :: URI
    channelTitle = URI
    tit}}
        Feed.Types.XMLFeed f :: Element
    f ->
          Element -> Feed
    Feed.Types.XMLFeed (Element -> Feed) -> Element -> Feed
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
            (\e :: Element
    e ->
               if Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "channel"
                 then Element -> Maybe Element
    forall a. a -> Maybe a
    Just
                        ((Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
                           (\e2 :: Element
    e2 ->
                              if Element -> Name
    elementName Element
    e2 Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "title"
                                then Element -> Maybe Element
    forall a. a -> Maybe a
    Just (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "title" URI
    tit)
                                else Maybe Element
    forall a. Maybe a
    Nothing)
                           Element
    e)
                 else Maybe Element
    forall a. Maybe a
    Nothing)
            Element
    f

    withFeedHome :: FeedSetter URLString
    withFeedHome :: FeedSetter URI
    withFeedHome url :: URI
    url fe :: Feed
    fe =
      case Feed
    fe of
        Feed.Types.AtomFeed f :: Feed
    f -> Feed -> Feed
    Feed.Types.AtomFeed Feed
    f {feedLinks :: [Link]
    feedLinks = Link
    newSelf Link -> [Link] -> [Link]
    forall a. a -> [a] -> [a]
    : Feed -> [Link]
    Atom.feedLinks Feed
    f}
          -- ToDo: fix, the <link> element is for the HTML home of the channel, not the
          -- location of the feed itself. Struggling to find if there is a common way
          -- to represent this outside of RSS 2.0 standard elements..
        Feed.Types.RSSFeed f :: RSS
    f -> RSS -> Feed
    Feed.Types.RSSFeed RSS
    f {rssChannel :: RSSChannel
    rssChannel = (RSS -> RSSChannel
    rssChannel RSS
    f) {rssLink :: URI
    rssLink = URI
    url}}
        Feed.Types.RSS1Feed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.RSS1Feed Feed
    f {feedChannel :: Channel
    feedChannel = (Feed -> Channel
    feedChannel Feed
    f) {channelURI :: URI
    channelURI = URI
    url}}
        Feed.Types.XMLFeed f :: Element
    f ->
          Element -> Feed
    Feed.Types.XMLFeed (Element -> Feed) -> Element -> Feed
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
            (\e :: Element
    e ->
               if Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "channel"
                 then Element -> Maybe Element
    forall a. a -> Maybe a
    Just
                        ((Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
                           (\e2 :: Element
    e2 ->
                              if Element -> Name
    elementName Element
    e2 Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "link"
                                then Element -> Maybe Element
    forall a. a -> Maybe a
    Just (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "link" URI
    url)
                                else Maybe Element
    forall a. Maybe a
    Nothing)
                           Element
    e)
                 else Maybe Element
    forall a. Maybe a
    Nothing)
            Element
    f
      where
        newSelf :: Link
    newSelf = (URI -> Link
    nullLink URI
    url) {linkRel :: Maybe (Either URI URI)
    linkRel = Either URI URI -> Maybe (Either URI URI)
    forall a. a -> Maybe a
    Just (URI -> Either URI URI
    forall a b. a -> Either a b
    Left "self"), linkType :: Maybe URI
    linkType = URI -> Maybe URI
    forall a. a -> Maybe a
    Just "application/atom+xml"}

    -- | 'withFeedHTML' sets the URL where an HTML version of the
    -- feed is published.
    withFeedHTML :: FeedSetter URLString
    withFeedHTML :: FeedSetter URI
    withFeedHTML url :: URI
    url fe :: Feed
    fe =
      case Feed
    fe of
        Feed.Types.AtomFeed f :: Feed
    f -> Feed -> Feed
    Feed.Types.AtomFeed Feed
    f {feedLinks :: [Link]
    feedLinks = Link
    newAlt Link -> [Link] -> [Link]
    forall a. a -> [a] -> [a]
    : Feed -> [Link]
    Atom.feedLinks Feed
    f}
        Feed.Types.RSSFeed f :: RSS
    f -> RSS -> Feed
    Feed.Types.RSSFeed RSS
    f {rssChannel :: RSSChannel
    rssChannel = (RSS -> RSSChannel
    rssChannel RSS
    f) {rssLink :: URI
    rssLink = URI
    url}}
        Feed.Types.RSS1Feed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.RSS1Feed Feed
    f {feedChannel :: Channel
    feedChannel = (Feed -> Channel
    feedChannel Feed
    f) {channelLink :: URI
    channelLink = URI
    url}}
        Feed.Types.XMLFeed f :: Element
    f ->
          Element -> Feed
    Feed.Types.XMLFeed (Element -> Feed) -> Element -> Feed
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
            (\e :: Element
    e ->
               if Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "channel"
                 then Element -> Maybe Element
    forall a. a -> Maybe a
    Just
                        ((Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
                           (\e2 :: Element
    e2 ->
                              if Element -> Name
    elementName Element
    e2 Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "link"
                                then Element -> Maybe Element
    forall a. a -> Maybe a
    Just (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "link" URI
    url)
                                else Maybe Element
    forall a. Maybe a
    Nothing)
                           Element
    e)
                 else Maybe Element
    forall a. Maybe a
    Nothing)
            Element
    f
      where
        newAlt :: Link
    newAlt = (URI -> Link
    nullLink URI
    url) {linkRel :: Maybe (Either URI URI)
    linkRel = Either URI URI -> Maybe (Either URI URI)
    forall a. a -> Maybe a
    Just (URI -> Either URI URI
    forall a b. a -> Either a b
    Left "alternate"), linkType :: Maybe URI
    linkType = URI -> Maybe URI
    forall a. a -> Maybe a
    Just "text/html"}

    -- | 'withFeedHTML' sets the URL where an HTML version of the
    -- feed is published.
    withFeedDescription :: FeedSetter Text
    withFeedDescription :: FeedSetter URI
    withFeedDescription desc :: URI
    desc fe :: Feed
    fe =
      case Feed
    fe of
        Feed.Types.AtomFeed f :: Feed
    f -> Feed -> Feed
    Feed.Types.AtomFeed Feed
    f {feedSubtitle :: Maybe TextContent
    feedSubtitle = TextContent -> Maybe TextContent
    forall a. a -> Maybe a
    Just (URI -> TextContent
    TextString URI
    desc)}
        Feed.Types.RSSFeed f :: RSS
    f ->
          RSS -> Feed
    Feed.Types.RSSFeed RSS
    f {rssChannel :: RSSChannel
    rssChannel = (RSS -> RSSChannel
    rssChannel RSS
    f) {rssDescription :: URI
    rssDescription = URI
    desc}}
        Feed.Types.RSS1Feed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.RSS1Feed Feed
    f {feedChannel :: Channel
    feedChannel = (Feed -> Channel
    feedChannel Feed
    f) {channelDesc :: URI
    channelDesc = URI
    desc}}
        Feed.Types.XMLFeed f :: Element
    f ->
          Element -> Feed
    Feed.Types.XMLFeed (Element -> Feed) -> Element -> Feed
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
            (\e :: Element
    e ->
               if Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "channel"
                 then Element -> Maybe Element
    forall a. a -> Maybe a
    Just
                        ((Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
                           (\e2 :: Element
    e2 ->
                              if Element -> Name
    elementName Element
    e2 Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "description"
                                then Element -> Maybe Element
    forall a. a -> Maybe a
    Just (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "description" URI
    desc)
                                else Maybe Element
    forall a. Maybe a
    Nothing)
                           Element
    e)
                 else Maybe Element
    forall a. Maybe a
    Nothing)
            Element
    f

    withFeedPubDate :: FeedSetter Text
    withFeedPubDate :: FeedSetter URI
    withFeedPubDate dateStr :: URI
    dateStr fe :: Feed
    fe =
      case Feed
    fe of
        Feed.Types.AtomFeed f :: Feed
    f -> Feed -> Feed
    Feed.Types.AtomFeed Feed
    f {feedUpdated :: URI
    feedUpdated = URI
    dateStr}
        Feed.Types.RSSFeed f :: RSS
    f ->
          RSS -> Feed
    Feed.Types.RSSFeed RSS
    f {rssChannel :: RSSChannel
    rssChannel = (RSS -> RSSChannel
    rssChannel RSS
    f) {rssPubDate :: Maybe URI
    rssPubDate = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    dateStr}}
        Feed.Types.RSS1Feed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.RSS1Feed (Feed -> Feed) -> Feed -> Feed
    forall a b. (a -> b) -> a -> b
    $
          case (DCItem -> Bool) -> [DCItem] -> ([DCItem], [DCItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break DCItem -> Bool
    isDate ([DCItem] -> ([DCItem], [DCItem]))
    -> [DCItem] -> ([DCItem], [DCItem])
    forall a b. (a -> b) -> a -> b
    $ Channel -> [DCItem]
    RSS1.channelDC (Feed -> Channel
    RSS1.feedChannel Feed
    f) of
            (as :: [DCItem]
    as, dci :: DCItem
    dci:bs :: [DCItem]
    bs) ->
              Feed
    f
                { feedChannel :: Channel
    RSS1.feedChannel =
                    (Feed -> Channel
    RSS1.feedChannel Feed
    f) {channelDC :: [DCItem]
    RSS1.channelDC = [DCItem]
    as [DCItem] -> [DCItem] -> [DCItem]
    forall a. [a] -> [a] -> [a]
    ++ DCItem
    dci {dcText :: URI
    dcText = URI
    dateStr} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : [DCItem]
    bs}
                }
            (_, []) ->
              Feed
    f
                { feedChannel :: Channel
    RSS1.feedChannel =
                    (Feed -> Channel
    RSS1.feedChannel Feed
    f)
                      { channelDC :: [DCItem]
    RSS1.channelDC =
                          DCItem :: DCInfo -> URI -> DCItem
    DCItem {dcElt :: DCInfo
    dcElt = DCInfo
    DC_Date, dcText :: URI
    dcText = URI
    dateStr} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    :
                          Channel -> [DCItem]
    RSS1.channelDC (Feed -> Channel
    RSS1.feedChannel Feed
    f)
                      }
                }
        Feed.Types.XMLFeed f :: Element
    f ->
          Element -> Feed
    Feed.Types.XMLFeed (Element -> Feed) -> Element -> Feed
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
            (\e :: Element
    e ->
               if Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "channel"
                 then Element -> Maybe Element
    forall a. a -> Maybe a
    Just
                        ((Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
                           (\e2 :: Element
    e2 ->
                              if Element -> Name
    elementName Element
    e2 Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "pubDate"
                                then Element -> Maybe Element
    forall a. a -> Maybe a
    Just (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "pubDate" URI
    dateStr)
                                else Maybe Element
    forall a. Maybe a
    Nothing)
                           Element
    e)
                 else Maybe Element
    forall a. Maybe a
    Nothing)
            Element
    f
      where
        isDate :: DCItem -> Bool
    isDate dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Date

    withFeedLastUpdate :: FeedSetter DateString
    withFeedLastUpdate :: FeedSetter URI
    withFeedLastUpdate dateStr :: URI
    dateStr fe :: Feed
    fe =
      case Feed
    fe of
        Feed.Types.AtomFeed f :: Feed
    f -> Feed -> Feed
    Feed.Types.AtomFeed Feed
    f {feedUpdated :: URI
    feedUpdated = URI
    dateStr}
        Feed.Types.RSSFeed f :: RSS
    f ->
          RSS -> Feed
    Feed.Types.RSSFeed RSS
    f {rssChannel :: RSSChannel
    rssChannel = (RSS -> RSSChannel
    rssChannel RSS
    f) {rssLastUpdate :: Maybe URI
    rssLastUpdate = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    dateStr}}
        Feed.Types.RSS1Feed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.RSS1Feed (Feed -> Feed) -> Feed -> Feed
    forall a b. (a -> b) -> a -> b
    $
          case (DCItem -> Bool) -> [DCItem] -> ([DCItem], [DCItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break DCItem -> Bool
    isDate ([DCItem] -> ([DCItem], [DCItem]))
    -> [DCItem] -> ([DCItem], [DCItem])
    forall a b. (a -> b) -> a -> b
    $ Channel -> [DCItem]
    RSS1.channelDC (Feed -> Channel
    RSS1.feedChannel Feed
    f) of
            (as :: [DCItem]
    as, dci :: DCItem
    dci:bs :: [DCItem]
    bs) ->
              Feed
    f
                { feedChannel :: Channel
    RSS1.feedChannel =
                    (Feed -> Channel
    RSS1.feedChannel Feed
    f) {channelDC :: [DCItem]
    RSS1.channelDC = [DCItem]
    as [DCItem] -> [DCItem] -> [DCItem]
    forall a. [a] -> [a] -> [a]
    ++ DCItem
    dci {dcText :: URI
    dcText = URI
    dateStr} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : [DCItem]
    bs}
                }
            (_, []) ->
              Feed
    f
                { feedChannel :: Channel
    RSS1.feedChannel =
                    (Feed -> Channel
    RSS1.feedChannel Feed
    f)
                      { channelDC :: [DCItem]
    RSS1.channelDC =
                          DCItem :: DCInfo -> URI -> DCItem
    DCItem {dcElt :: DCInfo
    dcElt = DCInfo
    DC_Date, dcText :: URI
    dcText = URI
    dateStr} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    :
                          Channel -> [DCItem]
    RSS1.channelDC (Feed -> Channel
    RSS1.feedChannel Feed
    f)
                      }
                }
        Feed.Types.XMLFeed f :: Element
    f ->
          Element -> Feed
    Feed.Types.XMLFeed (Element -> Feed) -> Element -> Feed
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
            (\e :: Element
    e ->
               if Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "channel"
                 then Element -> Maybe Element
    forall a. a -> Maybe a
    Just
                        ((Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
                           (\e2 :: Element
    e2 ->
                              if Element -> Name
    elementName Element
    e2 Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "lastUpdate"
                                then Element -> Maybe Element
    forall a. a -> Maybe a
    Just (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "lastUpdate" URI
    dateStr)
                                else Maybe Element
    forall a. Maybe a
    Nothing)
                           Element
    e)
                 else Maybe Element
    forall a. Maybe a
    Nothing)
            Element
    f
      where
        isDate :: DCItem -> Bool
    isDate dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Date

    -- | 'withFeedDate dt' is the composition of 'withFeedPubDate'
    -- and 'withFeedLastUpdate', setting both publication date and
    -- last update date to 'dt'. Notice that RSS2.0 is the only format
    -- supporting both pub and last-update.
    withFeedDate :: FeedSetter DateString
    withFeedDate :: FeedSetter URI
    withFeedDate dt :: URI
    dt f :: Feed
    f = FeedSetter URI
    withFeedPubDate URI
    dt (FeedSetter URI
    withFeedLastUpdate URI
    dt Feed
    f)

    withFeedLogoLink :: URLString -> FeedSetter URLString
    withFeedLogoLink :: URI -> FeedSetter URI
    withFeedLogoLink imgURL :: URI
    imgURL lnk :: URI
    lnk fe :: Feed
    fe =
      case Feed
    fe of
        Feed.Types.AtomFeed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.AtomFeed Feed
    f {feedLogo :: Maybe URI
    feedLogo = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    imgURL, feedLinks :: [Link]
    feedLinks = Link
    newSelf Link -> [Link] -> [Link]
    forall a. a -> [a] -> [a]
    : Feed -> [Link]
    Atom.feedLinks Feed
    f}
        Feed.Types.RSSFeed f :: RSS
    f ->
          RSS -> Feed
    Feed.Types.RSSFeed
            RSS
    f
              { rssChannel :: RSSChannel
    rssChannel =
                  (RSS -> RSSChannel
    rssChannel RSS
    f) {rssImage :: Maybe RSSImage
    rssImage = RSSImage -> Maybe RSSImage
    forall a. a -> Maybe a
    Just (RSSImage -> Maybe RSSImage) -> RSSImage -> Maybe RSSImage
    forall a b. (a -> b) -> a -> b
    $ URI -> URI -> URI -> RSSImage
    RSS.nullImage URI
    imgURL (RSSChannel -> URI
    rssTitle (RSS -> RSSChannel
    rssChannel RSS
    f)) URI
    lnk}
              }
        Feed.Types.RSS1Feed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.RSS1Feed (Feed -> Feed) -> Feed -> Feed
    forall a b. (a -> b) -> a -> b
    $
          Feed
    f
            { feedImage :: Maybe Image
    feedImage = Image -> Maybe Image
    forall a. a -> Maybe a
    Just (Image -> Maybe Image) -> Image -> Maybe Image
    forall a b. (a -> b) -> a -> b
    $ URI -> URI -> URI -> Image
    RSS1.nullImage URI
    imgURL (Channel -> URI
    RSS1.channelTitle (Feed -> Channel
    RSS1.feedChannel Feed
    f)) URI
    lnk
            , feedChannel :: Channel
    feedChannel = (Feed -> Channel
    feedChannel Feed
    f) {channelImageURI :: Maybe URI
    channelImageURI = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    imgURL}
            }
        Feed.Types.XMLFeed f :: Element
    f ->
          Element -> Feed
    Feed.Types.XMLFeed (Element -> Feed) -> Element -> Feed
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
            (\e :: Element
    e ->
               if Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "channel"
                 then Element -> Maybe Element
    forall a. a -> Maybe a
    Just
                        ((Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
                           (\e2 :: Element
    e2 ->
                              if Element -> Name
    elementName Element
    e2 Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "image"
                                then Element -> Maybe Element
    forall a. a -> Maybe a
    Just
                                       (Name -> [Element] -> Element
    forall t. ToNode t => Name -> t -> Element
    unode
                                          "image"
                                          [Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "url" URI
    imgURL, Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "title" URI
    title, Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "link" URI
    lnk])
                                else Maybe Element
    forall a. Maybe a
    Nothing)
                           Element
    e)
                 else Maybe Element
    forall a. Maybe a
    Nothing)
            Element
    f
          where title :: URI
    title =
                  case (Element -> Maybe Element)
    -> Maybe Element -> Maybe (Maybe Element)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Name -> Element -> Maybe Element
    findChild "title") (Name -> Element -> Maybe Element
    findChild "channel" Element
    f) of
                    Just (Just e1 :: Element
    e1) -> Element -> URI
    strContent Element
    e1
                    _ -> "feed_title" -- shouldn't happen..
      where
        newSelf :: Link
    newSelf = (URI -> Link
    nullLink URI
    lnk) {linkRel :: Maybe (Either URI URI)
    linkRel = Either URI URI -> Maybe (Either URI URI)
    forall a. a -> Maybe a
    Just (URI -> Either URI URI
    forall a b. a -> Either a b
    Left "self"), linkType :: Maybe URI
    linkType = URI -> Maybe URI
    forall a. a -> Maybe a
    Just "application/atom+xml"}

    withFeedLanguage :: FeedSetter Text
    withFeedLanguage :: FeedSetter URI
    withFeedLanguage lang :: URI
    lang fe :: Feed
    fe =
      case Feed
    fe of
        Feed.Types.AtomFeed f :: Feed
    f -> Feed -> Feed
    Feed.Types.AtomFeed Feed
    f {feedAttrs :: [Attr]
    Atom.feedAttrs = Attr
    langAttr Attr -> [Attr] -> [Attr]
    forall a. a -> [a] -> [a]
    : Feed -> [Attr]
    Atom.feedAttrs Feed
    f}
          where langAttr :: Attr
    langAttr = (Name
    name, [URI -> Content
    ContentText URI
    lang])
                name :: Name
    name = Name :: URI -> Maybe URI -> Maybe URI -> Name
    Name {nameLocalName :: URI
    nameLocalName = "lang", nameNamespace :: Maybe URI
    nameNamespace = Maybe URI
    forall a. Maybe a
    Nothing, namePrefix :: Maybe URI
    namePrefix = URI -> Maybe URI
    forall a. a -> Maybe a
    Just "xml"}
        Feed.Types.RSSFeed f :: RSS
    f ->
          RSS -> Feed
    Feed.Types.RSSFeed RSS
    f {rssChannel :: RSSChannel
    rssChannel = (RSS -> RSSChannel
    rssChannel RSS
    f) {rssLanguage :: Maybe URI
    rssLanguage = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    lang}}
        Feed.Types.RSS1Feed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.RSS1Feed (Feed -> Feed) -> Feed -> Feed
    forall a b. (a -> b) -> a -> b
    $
          case (DCItem -> Bool) -> [DCItem] -> ([DCItem], [DCItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break DCItem -> Bool
    isLang ([DCItem] -> ([DCItem], [DCItem]))
    -> [DCItem] -> ([DCItem], [DCItem])
    forall a b. (a -> b) -> a -> b
    $ Channel -> [DCItem]
    RSS1.channelDC (Feed -> Channel
    RSS1.feedChannel Feed
    f) of
            (as :: [DCItem]
    as, dci :: DCItem
    dci:bs :: [DCItem]
    bs) ->
              Feed
    f
                { feedChannel :: Channel
    RSS1.feedChannel =
                    (Feed -> Channel
    RSS1.feedChannel Feed
    f) {channelDC :: [DCItem]
    RSS1.channelDC = [DCItem]
    as [DCItem] -> [DCItem] -> [DCItem]
    forall a. [a] -> [a] -> [a]
    ++ DCItem
    dci {dcText :: URI
    dcText = URI
    lang} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : [DCItem]
    bs}
                }
            (_, []) ->
              Feed
    f
                { feedChannel :: Channel
    RSS1.feedChannel =
                    (Feed -> Channel
    RSS1.feedChannel Feed
    f)
                      { channelDC :: [DCItem]
    RSS1.channelDC =
                          DCItem :: DCInfo -> URI -> DCItem
    DCItem {dcElt :: DCInfo
    dcElt = DCInfo
    DC_Language, dcText :: URI
    dcText = URI
    lang} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    :
                          Channel -> [DCItem]
    RSS1.channelDC (Feed -> Channel
    RSS1.feedChannel Feed
    f)
                      }
                }
        Feed.Types.XMLFeed f :: Element
    f ->
          Element -> Feed
    Feed.Types.XMLFeed (Element -> Feed) -> Element -> Feed
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
            (\e :: Element
    e ->
               if Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "channel"
                 then Element -> Maybe Element
    forall a. a -> Maybe a
    Just
                        ((Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
                           (\e2 :: Element
    e2 ->
                              if Element -> Name
    elementName Element
    e2 Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "language"
                                then Element -> Maybe Element
    forall a. a -> Maybe a
    Just (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "language" URI
    lang)
                                else Maybe Element
    forall a. Maybe a
    Nothing)
                           Element
    e)
                 else Maybe Element
    forall a. Maybe a
    Nothing)
            Element
    f
      where
        isLang :: DCItem -> Bool
    isLang dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Language

    withFeedCategories :: FeedSetter [(Text, Maybe Text)]
    withFeedCategories :: FeedSetter [(URI, Maybe URI)]
    withFeedCategories cats :: [(URI, Maybe URI)]
    cats fe :: Feed
    fe =
      case Feed
    fe of
        Feed.Types.AtomFeed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.AtomFeed
            Feed
    f
              { feedCategories :: [Category]
    Atom.feedCategories =
                  ((URI, Maybe URI) -> Category) -> [(URI, Maybe URI)] -> [Category]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(t :: URI
    t, mb :: Maybe URI
    mb) -> (URI -> Category
    Atom.newCategory URI
    t) {catScheme :: Maybe URI
    Atom.catScheme = Maybe URI
    mb}) [(URI, Maybe URI)]
    cats [Category] -> [Category] -> [Category]
    forall a. [a] -> [a] -> [a]
    ++ Feed -> [Category]
    feedCategories Feed
    f
              }
        Feed.Types.RSSFeed f :: RSS
    f ->
          RSS -> Feed
    Feed.Types.RSSFeed
            RSS
    f
              { rssChannel :: RSSChannel
    rssChannel =
                  (RSS -> RSSChannel
    rssChannel RSS
    f)
                    { rssCategories :: [RSSCategory]
    RSS.rssCategories =
                        ((URI, Maybe URI) -> RSSCategory)
    -> [(URI, Maybe URI)] -> [RSSCategory]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(t :: URI
    t, mb :: Maybe URI
    mb) -> (URI -> RSSCategory
    RSS.newCategory URI
    t) {rssCategoryDomain :: Maybe URI
    RSS.rssCategoryDomain = Maybe URI
    mb}) [(URI, Maybe URI)]
    cats [RSSCategory] -> [RSSCategory] -> [RSSCategory]
    forall a. [a] -> [a] -> [a]
    ++
                        RSSChannel -> [RSSCategory]
    RSS.rssCategories (RSS -> RSSChannel
    rssChannel RSS
    f)
                    }
              }
        Feed.Types.RSS1Feed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.RSS1Feed
            Feed
    f
              { feedChannel :: Channel
    feedChannel =
                  (Feed -> Channel
    feedChannel Feed
    f)
                    { channelDC :: [DCItem]
    RSS1.channelDC =
                        ((URI, Maybe URI) -> DCItem) -> [(URI, Maybe URI)] -> [DCItem]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(t :: URI
    t, _) -> DCItem :: DCInfo -> URI -> DCItem
    DCItem {dcElt :: DCInfo
    dcElt = DCInfo
    DC_Subject, dcText :: URI
    dcText = URI
    t}) [(URI, Maybe URI)]
    cats [DCItem] -> [DCItem] -> [DCItem]
    forall a. [a] -> [a] -> [a]
    ++
                        Channel -> [DCItem]
    RSS1.channelDC (Feed -> Channel
    feedChannel Feed
    f)
                    }
              }
        Feed.Types.XMLFeed f :: Element
    f ->
          Element -> Feed
    Feed.Types.XMLFeed (Element -> Feed) -> Element -> Feed
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
            (\e :: Element
    e ->
               if Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "channel"
                 then Element -> Maybe Element
    forall a. a -> Maybe a
    Just
                        (((URI, Maybe URI) -> Element -> Element)
    -> Element -> [(URI, Maybe URI)] -> Element
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr
                           (\(t :: URI
    t, mb :: Maybe URI
    mb) acc :: Element
    acc ->
                              Element -> Element -> Element
    addChild
                                (Name -> [Attr] -> Element
    forall t. ToNode t => Name -> t -> Element
    unode
                                   "category"
                                   ((Attr -> [Attr])
    -> (URI -> Attr -> [Attr]) -> Maybe URI -> Attr -> [Attr]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (Attr -> [Attr] -> [Attr]
    forall a. a -> [a] -> [a]
    : []) (\v :: URI
    v x :: Attr
    x -> [URI -> URI -> Attr
    mkAttr "domain" URI
    v, Attr
    x]) Maybe URI
    mb (URI -> URI -> Attr
    mkAttr "term" URI
    t)))
                                Element
    acc)
                           Element
    e
                           [(URI, Maybe URI)]
    cats)
                 else Maybe Element
    forall a. Maybe a
    Nothing)
            Element
    f

    withFeedGenerator :: FeedSetter (Text, Maybe URLString)
    withFeedGenerator :: FeedSetter (URI, Maybe URI)
    withFeedGenerator (gen :: URI
    gen, mbURI :: Maybe URI
    mbURI) fe :: Feed
    fe =
      case Feed
    fe of
        Feed.Types.AtomFeed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.AtomFeed (Feed -> Feed) -> Feed -> Feed
    forall a b. (a -> b) -> a -> b
    $
          Feed
    f {feedGenerator :: Maybe Generator
    Atom.feedGenerator = Generator -> Maybe Generator
    forall a. a -> Maybe a
    Just ((URI -> Generator
    Atom.nullGenerator URI
    gen) {genURI :: Maybe URI
    Atom.genURI = Maybe URI
    mbURI})}
        Feed.Types.RSSFeed f :: RSS
    f ->
          RSS -> Feed
    Feed.Types.RSSFeed RSS
    f {rssChannel :: RSSChannel
    rssChannel = (RSS -> RSSChannel
    rssChannel RSS
    f) {rssGenerator :: Maybe URI
    rssGenerator = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    gen}}
        Feed.Types.RSS1Feed f :: Feed
    f ->
          Feed -> Feed
    Feed.Types.RSS1Feed (Feed -> Feed) -> Feed -> Feed
    forall a b. (a -> b) -> a -> b
    $
          case (DCItem -> Bool) -> [DCItem] -> ([DCItem], [DCItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break DCItem -> Bool
    isSource ([DCItem] -> ([DCItem], [DCItem]))
    -> [DCItem] -> ([DCItem], [DCItem])
    forall a b. (a -> b) -> a -> b
    $ Channel -> [DCItem]
    RSS1.channelDC (Feed -> Channel
    RSS1.feedChannel Feed
    f) of
            (as :: [DCItem]
    as, dci :: DCItem
    dci:bs :: [DCItem]
    bs) ->
              Feed
    f
                { feedChannel :: Channel
    RSS1.feedChannel =
                    (Feed -> Channel
    RSS1.feedChannel Feed
    f) {channelDC :: [DCItem]
    RSS1.channelDC = [DCItem]
    as [DCItem] -> [DCItem] -> [DCItem]
    forall a. [a] -> [a] -> [a]
    ++ DCItem
    dci {dcText :: URI
    dcText = URI
    gen} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : [DCItem]
    bs}
                }
            (_, []) ->
              Feed
    f
                { feedChannel :: Channel
    RSS1.feedChannel =
                    (Feed -> Channel
    RSS1.feedChannel Feed
    f)
                      { channelDC :: [DCItem]
    RSS1.channelDC =
                          DCItem :: DCInfo -> URI -> DCItem
    DCItem {dcElt :: DCInfo
    dcElt = DCInfo
    DC_Source, dcText :: URI
    dcText = URI
    gen} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : Channel -> [DCItem]
    RSS1.channelDC (Feed -> Channel
    RSS1.feedChannel Feed
    f)
                      }
                }
        Feed.Types.XMLFeed f :: Element
    f ->
          Element -> Feed
    Feed.Types.XMLFeed (Element -> Feed) -> Element -> Feed
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
            (\e :: Element
    e ->
               if Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "channel"
                 then Element -> Maybe Element
    forall a. a -> Maybe a
    Just
                        ((Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren
                           (\e2 :: Element
    e2 ->
                              if Element -> Name
    elementName Element
    e2 Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == "generator"
                                then Element -> Maybe Element
    forall a. a -> Maybe a
    Just (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "generator" URI
    gen)
                                else Maybe Element
    forall a. Maybe a
    Nothing)
                           Element
    e)
                 else Maybe Element
    forall a. Maybe a
    Nothing)
            Element
    f
      where
        isSource :: DCItem -> Bool
    isSource dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Source

    -- Item constructors (all the way to the end):
    atomEntryToItem :: Atom.Entry -> Feed.Types.Item
    atomEntryToItem :: Entry -> Item
    atomEntryToItem = Entry -> Item
    Feed.Types.AtomItem

    rssItemToItem :: RSS.RSSItem -> Feed.Types.Item
    rssItemToItem :: RSSItem -> Item
    rssItemToItem = RSSItem -> Item
    Feed.Types.RSSItem

    rdfItemToItem :: RSS1.Item -> Feed.Types.Item
    rdfItemToItem :: Item -> Item
    rdfItemToItem = Item -> Item
    Feed.Types.RSS1Item

    type ItemSetter a = a -> Feed.Types.Item -> Feed.Types.Item

    -- | 'withItemPubDate dt' associates the creation\/ publication date 'dt'
    -- with a feed item.
    withItemPubDate :: ItemSetter DateString
    withItemPubDate :: ItemSetter URI
    withItemPubDate dt :: URI
    dt fi :: Item
    fi =
      case Item
    fi of
        Feed.Types.AtomItem e :: Entry
    e -> Entry -> Item
    Feed.Types.AtomItem Entry
    e {entryUpdated :: URI
    Atom.entryUpdated = URI
    dt}
        Feed.Types.RSSItem i :: RSSItem
    i -> RSSItem -> Item
    Feed.Types.RSSItem RSSItem
    i {rssItemPubDate :: Maybe URI
    RSS.rssItemPubDate = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    dt}
        Feed.Types.RSS1Item i :: Item
    i ->
          case (DCItem -> Bool) -> [DCItem] -> ([DCItem], [DCItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break DCItem -> Bool
    isDate ([DCItem] -> ([DCItem], [DCItem]))
    -> [DCItem] -> ([DCItem], [DCItem])
    forall a b. (a -> b) -> a -> b
    $ Item -> [DCItem]
    RSS1.itemDC Item
    i of
            (as :: [DCItem]
    as, dci :: DCItem
    dci:bs :: [DCItem]
    bs) -> Item -> Item
    Feed.Types.RSS1Item Item
    i {itemDC :: [DCItem]
    RSS1.itemDC = [DCItem]
    as [DCItem] -> [DCItem] -> [DCItem]
    forall a. [a] -> [a] -> [a]
    ++ DCItem
    dci {dcText :: URI
    dcText = URI
    dt} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : [DCItem]
    bs}
            (_, []) ->
              Item -> Item
    Feed.Types.RSS1Item
                Item
    i {itemDC :: [DCItem]
    RSS1.itemDC = DCItem :: DCInfo -> URI -> DCItem
    DCItem {dcElt :: DCInfo
    dcElt = DCInfo
    DC_Date, dcText :: URI
    dcText = URI
    dt} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : Item -> [DCItem]
    RSS1.itemDC Item
    i}
        Feed.Types.XMLItem i :: Element
    i ->
          Element -> Item
    Feed.Types.XMLItem (Element -> Item) -> Element -> Item
    forall a b. (a -> b) -> a -> b
    $
          Element -> Element -> Element
    addChild (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "pubDate" URI
    dt) (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ (Element -> Bool) -> Element -> Element
    filterChildren (\e :: Element
    e -> Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "pubDate") Element
    i
      where
        isDate :: DCItem -> Bool
    isDate dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Date

    -- | 'withItemDate' is a synonym for 'withItemPubDate'.
    withItemDate :: ItemSetter DateString
    withItemDate :: ItemSetter URI
    withItemDate = ItemSetter URI
    withItemPubDate

    -- | 'withItemTitle myTitle' associates a new title, 'myTitle',
    -- with a feed item.
    withItemTitle :: ItemSetter Text
    withItemTitle :: ItemSetter URI
    withItemTitle tit :: URI
    tit fi :: Item
    fi =
      case Item
    fi of
        Feed.Types.AtomItem e :: Entry
    e -> Entry -> Item
    Feed.Types.AtomItem Entry
    e {entryTitle :: TextContent
    Atom.entryTitle = URI -> TextContent
    TextString URI
    tit}
        Feed.Types.RSSItem i :: RSSItem
    i -> RSSItem -> Item
    Feed.Types.RSSItem RSSItem
    i {rssItemTitle :: Maybe URI
    RSS.rssItemTitle = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    tit}
        Feed.Types.RSS1Item i :: Item
    i -> Item -> Item
    Feed.Types.RSS1Item Item
    i {itemTitle :: URI
    RSS1.itemTitle = URI
    tit}
        Feed.Types.XMLItem i :: Element
    i ->
          Element -> Item
    Feed.Types.XMLItem (Element -> Item) -> Element -> Item
    forall a b. (a -> b) -> a -> b
    $
          Element -> Element -> Element
    addChild (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "title" URI
    tit) (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ (Element -> Bool) -> Element -> Element
    filterChildren (\e :: Element
    e -> Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "title") Element
    i

    -- | 'withItemAuthor auStr' associates new author info
    -- with a feed item.
    withItemAuthor :: ItemSetter Text
    withItemAuthor :: ItemSetter URI
    withItemAuthor au :: URI
    au fi :: Item
    fi =
      case Item
    fi of
        Feed.Types.AtomItem e :: Entry
    e ->
          Entry -> Item
    Feed.Types.AtomItem
            Entry
    e {entryAuthors :: [Person]
    Atom.entryAuthors = [Person
    nullPerson {personName :: URI
    personName = URI
    au, personURI :: Maybe URI
    personURI = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    au}]}
        Feed.Types.RSSItem i :: RSSItem
    i -> RSSItem -> Item
    Feed.Types.RSSItem RSSItem
    i {rssItemAuthor :: Maybe URI
    RSS.rssItemAuthor = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    au}
        Feed.Types.RSS1Item i :: Item
    i ->
          case (DCItem -> Bool) -> [DCItem] -> ([DCItem], [DCItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break DCItem -> Bool
    isAuthor ([DCItem] -> ([DCItem], [DCItem]))
    -> [DCItem] -> ([DCItem], [DCItem])
    forall a b. (a -> b) -> a -> b
    $ Item -> [DCItem]
    RSS1.itemDC Item
    i of
            (as :: [DCItem]
    as, dci :: DCItem
    dci:bs :: [DCItem]
    bs) -> Item -> Item
    Feed.Types.RSS1Item Item
    i {itemDC :: [DCItem]
    RSS1.itemDC = [DCItem]
    as [DCItem] -> [DCItem] -> [DCItem]
    forall a. [a] -> [a] -> [a]
    ++ DCItem
    dci {dcText :: URI
    dcText = URI
    au} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : [DCItem]
    bs}
            (_, []) ->
              Item -> Item
    Feed.Types.RSS1Item
                Item
    i {itemDC :: [DCItem]
    RSS1.itemDC = DCItem :: DCInfo -> URI -> DCItem
    DCItem {dcElt :: DCInfo
    dcElt = DCInfo
    DC_Creator, dcText :: URI
    dcText = URI
    au} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : Item -> [DCItem]
    RSS1.itemDC Item
    i}
        Feed.Types.XMLItem i :: Element
    i ->
          Element -> Item
    Feed.Types.XMLItem (Element -> Item) -> Element -> Item
    forall a b. (a -> b) -> a -> b
    $
          Element -> Element -> Element
    addChild (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "author" URI
    au) (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ (Element -> Bool) -> Element -> Element
    filterChildren (\e :: Element
    e -> Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "author") Element
    i
      where
        isAuthor :: DCItem -> Bool
    isAuthor dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Creator

    -- | 'withItemFeedLink name myFeed' associates the parent feed URL 'myFeed'
    -- with a feed item. It is labelled as 'name'.
    withItemFeedLink :: Text -> ItemSetter Text
    withItemFeedLink :: URI -> ItemSetter URI
    withItemFeedLink tit :: URI
    tit url :: URI
    url fi :: Item
    fi =
      case Item
    fi of
        Feed.Types.AtomItem e :: Entry
    e ->
          Entry -> Item
    Feed.Types.AtomItem
            Entry
    e
              { entrySource :: Maybe Source
    Atom.entrySource =
                  Source -> Maybe Source
    forall a. a -> Maybe a
    Just Source
    Atom.nullSource {sourceId :: Maybe URI
    sourceId = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    url, sourceTitle :: Maybe TextContent
    sourceTitle = TextContent -> Maybe TextContent
    forall a. a -> Maybe a
    Just (URI -> TextContent
    TextString URI
    tit)}
              }
        Feed.Types.RSSItem i :: RSSItem
    i -> RSSItem -> Item
    Feed.Types.RSSItem RSSItem
    i {rssItemSource :: Maybe RSSSource
    RSS.rssItemSource = RSSSource -> Maybe RSSSource
    forall a. a -> Maybe a
    Just (URI -> URI -> RSSSource
    RSS.nullSource URI
    url URI
    tit)}
        Feed.Types.RSS1Item i :: Item
    i -> Item -> Item
    Feed.Types.RSS1Item Item
    i {itemTitle :: URI
    RSS1.itemTitle = URI
    tit}
        Feed.Types.XMLItem i :: Element
    i ->
          Element -> Item
    Feed.Types.XMLItem (Element -> Item) -> Element -> Item
    forall a b. (a -> b) -> a -> b
    $
          Element -> Element -> Element
    addChild (Name -> ([Attr], URI) -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "source" ([URI -> URI -> Attr
    mkAttr "url" URI
    url], URI
    tit)) (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Bool) -> Element -> Element
    filterChildren (\e :: Element
    e -> Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "source") Element
    i

    -- | 'withItemCommentLink url' sets the URL reference to the comment page to 'url'.
    withItemCommentLink :: ItemSetter Text
    withItemCommentLink :: ItemSetter URI
    withItemCommentLink url :: URI
    url fi :: Item
    fi =
      case Item
    fi of
        Feed.Types.AtomItem e :: Entry
    e ->
          Entry -> Item
    Feed.Types.AtomItem
            Entry
    e {entryLinks :: [Link]
    Atom.entryLinks = ((URI -> Link
    nullLink URI
    url) {linkRel :: Maybe (Either URI URI)
    linkRel = Either URI URI -> Maybe (Either URI URI)
    forall a. a -> Maybe a
    Just (URI -> Either URI URI
    forall a b. a -> Either a b
    Left "replies")}) Link -> [Link] -> [Link]
    forall a. a -> [a] -> [a]
    : Entry -> [Link]
    Atom.entryLinks Entry
    e}
        Feed.Types.RSSItem i :: RSSItem
    i -> RSSItem -> Item
    Feed.Types.RSSItem RSSItem
    i {rssItemComments :: Maybe URI
    RSS.rssItemComments = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    url}
        Feed.Types.RSS1Item i :: Item
    i ->
          case (DCItem -> Bool) -> [DCItem] -> ([DCItem], [DCItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break DCItem -> Bool
    isRel ([DCItem] -> ([DCItem], [DCItem]))
    -> [DCItem] -> ([DCItem], [DCItem])
    forall a b. (a -> b) -> a -> b
    $ Item -> [DCItem]
    RSS1.itemDC Item
    i of
            (as :: [DCItem]
    as, dci :: DCItem
    dci:bs :: [DCItem]
    bs) -> Item -> Item
    Feed.Types.RSS1Item Item
    i {itemDC :: [DCItem]
    RSS1.itemDC = [DCItem]
    as [DCItem] -> [DCItem] -> [DCItem]
    forall a. [a] -> [a] -> [a]
    ++ DCItem
    dci {dcText :: URI
    dcText = URI
    url} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : [DCItem]
    bs}
            (_, []) ->
              Item -> Item
    Feed.Types.RSS1Item
                Item
    i {itemDC :: [DCItem]
    RSS1.itemDC = DCItem :: DCInfo -> URI -> DCItem
    DCItem {dcElt :: DCInfo
    dcElt = DCInfo
    DC_Relation, dcText :: URI
    dcText = URI
    url} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : Item -> [DCItem]
    RSS1.itemDC Item
    i}
        Feed.Types.XMLItem i :: Element
    i ->
          Element -> Item
    Feed.Types.XMLItem (Element -> Item) -> Element -> Item
    forall a b. (a -> b) -> a -> b
    $
          Element -> Element -> Element
    addChild (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "comments" URI
    url) (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ (Element -> Bool) -> Element -> Element
    filterChildren (\e :: Element
    e -> Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "comments") Element
    i
      where
        isRel :: DCItem -> Bool
    isRel dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Relation

    -- | 'withItemEnclosure url mbTy len' sets the URL reference to the comment page to 'url'.
    withItemEnclosure :: Text -> Maybe Text -> ItemSetter (Maybe Integer)
    withItemEnclosure :: URI -> Maybe URI -> ItemSetter (Maybe Integer)
    withItemEnclosure url :: URI
    url ty :: Maybe URI
    ty mb_len :: Maybe Integer
    mb_len fi :: Item
    fi =
      case Item
    fi of
        Feed.Types.AtomItem e :: Entry
    e ->
          Entry -> Item
    Feed.Types.AtomItem
            Entry
    e
              { entryLinks :: [Link]
    Atom.entryLinks =
                  ((URI -> Link
    nullLink URI
    url)
                     { linkRel :: Maybe (Either URI URI)
    linkRel = Either URI URI -> Maybe (Either URI URI)
    forall a. a -> Maybe a
    Just (URI -> Either URI URI
    forall a b. a -> Either a b
    Left "enclosure")
                     , linkType :: Maybe URI
    linkType = Maybe URI
    ty
                     , linkLength :: Maybe URI
    linkLength = (Integer -> URI) -> Maybe Integer -> Maybe URI
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ([Char] -> URI
    pack ([Char] -> URI) -> (Integer -> [Char]) -> Integer -> URI
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> [Char]
    forall a. Show a => a -> [Char]
    show) Maybe Integer
    mb_len
                     }) Link -> [Link] -> [Link]
    forall a. a -> [a] -> [a]
    :
                  Entry -> [Link]
    Atom.entryLinks Entry
    e
              }
        Feed.Types.RSSItem i :: RSSItem
    i ->
          RSSItem -> Item
    Feed.Types.RSSItem
            RSSItem
    i {rssItemEnclosure :: Maybe RSSEnclosure
    RSS.rssItemEnclosure = RSSEnclosure -> Maybe RSSEnclosure
    forall a. a -> Maybe a
    Just (URI -> Maybe Integer -> URI -> RSSEnclosure
    nullEnclosure URI
    url Maybe Integer
    mb_len (URI -> Maybe URI -> URI
    forall a. a -> Maybe a -> a
    fromMaybe "text/html" Maybe URI
    ty))}
        Feed.Types.RSS1Item i :: Item
    i ->
          Item -> Item
    Feed.Types.RSS1Item
            Item
    i
              { itemContent :: [ContentInfo]
    RSS1.itemContent =
                  ContentInfo
    nullContentInfo {contentURI :: Maybe URI
    contentURI = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    url, contentFormat :: Maybe URI
    contentFormat = Maybe URI
    ty} ContentInfo -> [ContentInfo] -> [ContentInfo]
    forall a. a -> [a] -> [a]
    : Item -> [ContentInfo]
    RSS1.itemContent Item
    i
              }
        Feed.Types.XMLItem i :: Element
    i ->
          Element -> Item
    Feed.Types.XMLItem (Element -> Item) -> Element -> Item
    forall a b. (a -> b) -> a -> b
    $
          Element -> Element -> Element
    addChild
            ((Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "enclosure" URI
    url)
               {elementAttributes :: [Attr]
    elementAttributes = [URI -> URI -> Attr
    mkAttr "length" "0", URI -> URI -> Attr
    mkAttr "type" (URI -> Maybe URI -> URI
    forall a. a -> Maybe a -> a
    fromMaybe "text/html" Maybe URI
    ty)]}) (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Bool) -> Element -> Element
    filterChildren (\e :: Element
    e -> Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "enclosure") Element
    i

    -- | 'withItemId isURL id' associates new unique identifier with a feed item.
    -- If 'isURL' is 'True', then the id is assumed to point to a valid web resource.
    withItemId :: Bool -> ItemSetter Text
    withItemId :: Bool -> ItemSetter URI
    withItemId isURL :: Bool
    isURL idS :: URI
    idS fi :: Item
    fi =
      case Item
    fi of
        Feed.Types.AtomItem e :: Entry
    e -> Entry -> Item
    Feed.Types.AtomItem Entry
    e {entryId :: URI
    Atom.entryId = URI
    idS}
        Feed.Types.RSSItem i :: RSSItem
    i ->
          RSSItem -> Item
    Feed.Types.RSSItem
            RSSItem
    i {rssItemGuid :: Maybe RSSGuid
    RSS.rssItemGuid = RSSGuid -> Maybe RSSGuid
    forall a. a -> Maybe a
    Just (URI -> RSSGuid
    nullGuid URI
    idS) {rssGuidPermanentURL :: Maybe Bool
    rssGuidPermanentURL = Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    isURL}}
        Feed.Types.RSS1Item i :: Item
    i ->
          case (DCItem -> Bool) -> [DCItem] -> ([DCItem], [DCItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break DCItem -> Bool
    isId ([DCItem] -> ([DCItem], [DCItem]))
    -> [DCItem] -> ([DCItem], [DCItem])
    forall a b. (a -> b) -> a -> b
    $ Item -> [DCItem]
    RSS1.itemDC Item
    i of
            (as :: [DCItem]
    as, dci :: DCItem
    dci:bs :: [DCItem]
    bs) -> Item -> Item
    Feed.Types.RSS1Item Item
    i {itemDC :: [DCItem]
    RSS1.itemDC = [DCItem]
    as [DCItem] -> [DCItem] -> [DCItem]
    forall a. [a] -> [a] -> [a]
    ++ DCItem
    dci {dcText :: URI
    dcText = URI
    idS} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : [DCItem]
    bs}
            (_, []) ->
              Item -> Item
    Feed.Types.RSS1Item
                Item
    i {itemDC :: [DCItem]
    RSS1.itemDC = DCItem :: DCInfo -> URI -> DCItem
    DCItem {dcElt :: DCInfo
    dcElt = DCInfo
    DC_Identifier, dcText :: URI
    dcText = URI
    idS} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : Item -> [DCItem]
    RSS1.itemDC Item
    i}
        Feed.Types.XMLItem i :: Element
    i ->
          Element -> Item
    Feed.Types.XMLItem (Element -> Item) -> Element -> Item
    forall a b. (a -> b) -> a -> b
    $
          Element -> Element -> Element
    addChild (Name -> ([Attr], URI) -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "guid" ([URI -> URI -> Attr
    mkAttr "isPermaLink" (Bool -> URI
    forall a. Show a => a -> URI
    showBool Bool
    isURL)], URI
    idS)) (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $
          (Element -> Bool) -> Element -> Element
    filterChildren (\e :: Element
    e -> Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "guid") Element
    i
      where
        showBool :: a -> URI
    showBool x :: a
    x = [Char] -> URI
    pack ([Char] -> URI) -> [Char] -> URI
    forall a b. (a -> b) -> a -> b
    $ (Char -> Char) -> [Char] -> [Char]
    forall a b. (a -> b) -> [a] -> [b]
    map Char -> Char
    toLower (a -> [Char]
    forall a. Show a => a -> [Char]
    show a
    x)
        isId :: DCItem -> Bool
    isId dc :: DCItem
    dc = DCItem -> DCInfo
    dcElt DCItem
    dc DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Identifier

    -- | 'withItemDescription desc' associates a new descriptive string (aka summary)
    -- with a feed item.
    withItemDescription :: ItemSetter Text
    withItemDescription :: ItemSetter URI
    withItemDescription desc :: URI
    desc fi :: Item
    fi =
      case Item
    fi of
        Feed.Types.AtomItem e :: Entry
    e -> Entry -> Item
    Feed.Types.AtomItem Entry
    e {entrySummary :: Maybe TextContent
    Atom.entrySummary = TextContent -> Maybe TextContent
    forall a. a -> Maybe a
    Just (URI -> TextContent
    TextString URI
    desc)}
        Feed.Types.RSSItem i :: RSSItem
    i -> RSSItem -> Item
    Feed.Types.RSSItem RSSItem
    i {rssItemDescription :: Maybe URI
    RSS.rssItemDescription = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    desc}
        Feed.Types.RSS1Item i :: Item
    i -> Item -> Item
    Feed.Types.RSS1Item Item
    i {itemDesc :: Maybe URI
    RSS1.itemDesc = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    desc}
        Feed.Types.XMLItem i :: Element
    i ->
          Element -> Item
    Feed.Types.XMLItem (Element -> Item) -> Element -> Item
    forall a b. (a -> b) -> a -> b
    $
          Element -> Element -> Element
    addChild (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "description" URI
    desc) (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ (Element -> Bool) -> Element -> Element
    filterChildren (\e :: Element
    e -> Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "description") Element
    i

    -- | 'withItemRights rightStr' associates the rights information 'rightStr'
    -- with a feed item.
    withItemRights :: ItemSetter Text
    withItemRights :: ItemSetter URI
    withItemRights desc :: URI
    desc fi :: Item
    fi =
      case Item
    fi of
        Feed.Types.AtomItem e :: Entry
    e -> Entry -> Item
    Feed.Types.AtomItem Entry
    e {entryRights :: Maybe TextContent
    Atom.entryRights = TextContent -> Maybe TextContent
    forall a. a -> Maybe a
    Just (URI -> TextContent
    TextString URI
    desc)}
         -- Note: per-item copyright information isn't supported by RSS2.0 (and earlier editions),
         -- you can only attach this at the feed/channel level. So, there's not much we can do
         -- except dropping the information on the floor here. (Rolling our own attribute or
         -- extension element is an option, but would prefer if someone else had started that
         -- effort already.
        Feed.Types.RSSItem {} -> Item
    fi
        Feed.Types.RSS1Item i :: Item
    i ->
          case (DCItem -> Bool) -> [DCItem] -> ([DCItem], [DCItem])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    break ((DCInfo -> DCInfo -> Bool
    forall a. Eq a => a -> a -> Bool
    == DCInfo
    DC_Rights) (DCInfo -> Bool) -> (DCItem -> DCInfo) -> DCItem -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DCItem -> DCInfo
    dcElt) ([DCItem] -> ([DCItem], [DCItem]))
    -> [DCItem] -> ([DCItem], [DCItem])
    forall a b. (a -> b) -> a -> b
    $ Item -> [DCItem]
    RSS1.itemDC Item
    i of
            (as :: [DCItem]
    as, dci :: DCItem
    dci:bs :: [DCItem]
    bs) -> Item -> Item
    Feed.Types.RSS1Item Item
    i {itemDC :: [DCItem]
    RSS1.itemDC = [DCItem]
    as [DCItem] -> [DCItem] -> [DCItem]
    forall a. [a] -> [a] -> [a]
    ++ DCItem
    dci {dcText :: URI
    dcText = URI
    desc} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : [DCItem]
    bs}
            (_, []) ->
              Item -> Item
    Feed.Types.RSS1Item
                Item
    i {itemDC :: [DCItem]
    RSS1.itemDC = DCItem :: DCInfo -> URI -> DCItem
    DCItem {dcElt :: DCInfo
    dcElt = DCInfo
    DC_Rights, dcText :: URI
    dcText = URI
    desc} DCItem -> [DCItem] -> [DCItem]
    forall a. a -> [a] -> [a]
    : Item -> [DCItem]
    RSS1.itemDC Item
    i}
         -- Since we're so far assuming that a shallow XML rep. of an item
         -- is of RSS2.0 ilk, pinning on the rights info is hard (see above.)
        Feed.Types.XMLItem {} -> Item
    fi

    -- | 'withItemTitle myLink' associates a new URL, 'myLink',
    -- with a feed item.
    withItemLink :: ItemSetter URLString
    withItemLink :: ItemSetter URI
    withItemLink url :: URI
    url fi :: Item
    fi =
      case Item
    fi of
        Feed.Types.AtomItem e :: Entry
    e ->
          Entry -> Item
    Feed.Types.AtomItem Entry
    e {entryLinks :: [Link]
    Atom.entryLinks = URI -> [Link] -> [Link]
    replaceAlternate URI
    url (Entry -> [Link]
    Atom.entryLinks Entry
    e)}
        Feed.Types.RSSItem i :: RSSItem
    i -> RSSItem -> Item
    Feed.Types.RSSItem RSSItem
    i {rssItemLink :: Maybe URI
    RSS.rssItemLink = URI -> Maybe URI
    forall a. a -> Maybe a
    Just URI
    url}
        Feed.Types.RSS1Item i :: Item
    i -> Item -> Item
    Feed.Types.RSS1Item Item
    i {itemLink :: URI
    RSS1.itemLink = URI
    url}
        Feed.Types.XMLItem i :: Element
    i ->
          Element -> Item
    Feed.Types.XMLItem (Element -> Item) -> Element -> Item
    forall a b. (a -> b) -> a -> b
    $
          Element -> Element -> Element
    addChild (Name -> URI -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "link" URI
    url) (Element -> Element) -> Element -> Element
    forall a b. (a -> b) -> a -> b
    $ (Element -> Bool) -> Element -> Element
    filterChildren (\e :: Element
    e -> Element -> Name
    elementName Element
    e Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "link") Element
    i
      where
        replaceAlternate :: URI -> [Link] -> [Link]
    replaceAlternate _ [] = []
        replaceAlternate x :: URI
    x (lr :: Link
    lr:xs :: [Link]
    xs)
          | Maybe (Either URI URI) -> URI
    forall p. IsString p => Maybe (Either p p) -> p
    toStr (Link -> Maybe (Either URI URI)
    Atom.linkRel Link
    lr) URI -> URI -> Bool
    forall a. Eq a => a -> a -> Bool
    == "alternate" = Link
    lr {linkHref :: URI
    Atom.linkHref = URI
    x} Link -> [Link] -> [Link]
    forall a. a -> [a] -> [a]
    : [Link]
    xs
          | Bool
    otherwise = Link
    lr Link -> [Link] -> [Link]
    forall a. a -> [a] -> [a]
    : URI -> [Link] -> [Link]
    replaceAlternate URI
    x [Link]
    xs
        toStr :: Maybe (Either p p) -> p
    toStr Nothing = ""
        toStr (Just (Left x :: p
    x)) = p
    x
        toStr (Just (Right x :: p
    x)) = p
    x

    withItemCategories :: ItemSetter [(Text, Maybe Text)]
    withItemCategories :: ItemSetter [(URI, Maybe URI)]
    withItemCategories cats :: [(URI, Maybe URI)]
    cats fi :: Item
    fi =
      case Item
    fi of
        Feed.Types.AtomItem e :: Entry
    e ->
          Entry -> Item
    Feed.Types.AtomItem
            Entry
    e
              { entryCategories :: [Category]
    Atom.entryCategories =
                  ((URI, Maybe URI) -> Category) -> [(URI, Maybe URI)] -> [Category]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(t :: URI
    t, mb :: Maybe URI
    mb) -> (URI -> Category
    Atom.newCategory URI
    t) {catScheme :: Maybe URI
    Atom.catScheme = Maybe URI
    mb}) [(URI, Maybe URI)]
    cats [Category] -> [Category] -> [Category]
    forall a. [a] -> [a] -> [a]
    ++ Entry -> [Category]
    entryCategories Entry
    e
              }
        Feed.Types.RSSItem i :: RSSItem
    i ->
          RSSItem -> Item
    Feed.Types.RSSItem
            RSSItem
    i
              { rssItemCategories :: [RSSCategory]
    RSS.rssItemCategories =
                  ((URI, Maybe URI) -> RSSCategory)
    -> [(URI, Maybe URI)] -> [RSSCategory]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(t :: URI
    t, mb :: Maybe URI
    mb) -> (URI -> RSSCategory
    RSS.newCategory URI
    t) {rssCategoryDomain :: Maybe URI
    RSS.rssCategoryDomain = Maybe URI
    mb}) [(URI, Maybe URI)]
    cats [RSSCategory] -> [RSSCategory] -> [RSSCategory]
    forall a. [a] -> [a] -> [a]
    ++
                  RSSItem -> [RSSCategory]
    rssItemCategories RSSItem
    i
              }
        Feed.Types.RSS1Item i :: Item
    i ->
          Item -> Item
    Feed.Types.RSS1Item
            Item
    i
              { itemDC :: [DCItem]
    RSS1.itemDC =
                  ((URI, Maybe URI) -> DCItem) -> [(URI, Maybe URI)] -> [DCItem]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(t :: URI
    t, _) -> DCItem :: DCInfo -> URI -> DCItem
    DCItem {dcElt :: DCInfo
    dcElt = DCInfo
    DC_Subject, dcText :: URI
    dcText = URI
    t}) [(URI, Maybe URI)]
    cats [DCItem] -> [DCItem] -> [DCItem]
    forall a. [a] -> [a] -> [a]
    ++ Item -> [DCItem]
    RSS1.itemDC Item
    i
              }
        Feed.Types.XMLItem i :: Element
    i ->
          Element -> Item
    Feed.Types.XMLItem (Element -> Item) -> Element -> Item
    forall a b. (a -> b) -> a -> b
    $
          ((URI, Maybe URI) -> Element -> Element)
    -> Element -> [(URI, Maybe URI)] -> Element
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr
            (\(t :: URI
    t, mb :: Maybe URI
    mb) acc :: Element
    acc ->
               Element -> Element -> Element
    addChild
                 (Name -> [Attr] -> Element
    forall t. ToNode t => Name -> t -> Element
    unode "category" ((Attr -> [Attr])
    -> (URI -> Attr -> [Attr]) -> Maybe URI -> Attr -> [Attr]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (Attr -> [Attr] -> [Attr]
    forall a. a -> [a] -> [a]
    : []) (\v :: URI
    v x :: Attr
    x -> [URI -> URI -> Attr
    mkAttr "domain" URI
    v, Attr
    x]) Maybe URI
    mb (URI -> URI -> Attr
    mkAttr "term" URI
    t)))
                 Element
    acc)
            Element
    i
            [(URI, Maybe URI)]
    cats

    -- helpers..
    filterChildren :: (XML.Element -> Bool) -> XML.Element -> XML.Element
    filterChildren :: (Element -> Bool) -> Element -> Element
    filterChildren pre :: Element -> Bool
    pre e :: Element
    e =
      case Element -> [Node]
    elementNodes Element
    e of
        [] -> Element
    e
        cs :: [Node]
    cs -> Element
    e {elementNodes :: [Node]
    elementNodes = (Node -> Maybe Node) -> [Node] -> [Node]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe Node -> Maybe Node
    filterElt [Node]
    cs}
      where
        filterElt :: Node -> Maybe Node
    filterElt xe :: Node
    xe@(XML.NodeElement el :: Element
    el)
          | Element -> Bool
    pre Element
    el = Node -> Maybe Node
    forall a. a -> Maybe a
    Just Node
    xe
          | Bool
    otherwise = Maybe Node
    forall a. Maybe a
    Nothing
        filterElt xe :: Node
    xe = Node -> Maybe Node
    forall a. a -> Maybe a
    Just Node
    xe

    addChild :: XML.Element -> XML.Element -> XML.Element
    addChild :: Element -> Element -> Element
    addChild a :: Element
    a b :: Element
    b = Element
    b {elementNodes :: [Node]
    elementNodes = Element -> Node
    XML.NodeElement Element
    a Node -> [Node] -> [Node]
    forall a. a -> [a] -> [a]
    : Element -> [Node]
    elementNodes Element
    b}

    mapMaybeChildren :: (XML.Element -> Maybe XML.Element) -> XML.Element -> XML.Element
    mapMaybeChildren :: (Element -> Maybe Element) -> Element -> Element
    mapMaybeChildren f :: Element -> Maybe Element
    f e :: Element
    e =
      case Element -> [Node]
    elementNodes Element
    e of
        [] -> Element
    e
        cs :: [Node]
    cs -> Element
    e {elementNodes :: [Node]
    elementNodes = (Node -> Node) -> [Node] -> [Node]
    forall a b. (a -> b) -> [a] -> [b]
    map Node -> Node
    procElt [Node]
    cs}
      where
        procElt :: Node -> Node
    procElt xe :: Node
    xe@(XML.NodeElement el :: Element
    el) =
          case Element -> Maybe Element
    f Element
    el of
            Nothing -> Node
    xe
            Just el1 :: Element
    el1 -> Element -> Node
    XML.NodeElement Element
    el1
        procElt xe :: Node
    xe = Node
    xe