feed_parser/lib/feed_parser.ex

52 lines
1.4 KiB
Elixir
Raw Permalink Normal View History

2019-08-31 23:02:41 +00:00
defmodule FeedParser do
2019-09-01 03:25:10 +00:00
@moduledoc """
FeedParser is a for parsing feeds of various formats into a unified representation.
The currently supported formats are:
- RSS 2.0
- Atom
- JSON Feed
- RSS-in-JSON
"""
2019-08-31 23:18:03 +00:00
@default_parsers [
2019-09-01 03:25:10 +00:00
FeedParser.Parser.RSS2,
FeedParser.Parser.Atom,
FeedParser.Parser.JSONFeed,
FeedParser.Parser.RSSInJSON
2019-08-31 23:18:03 +00:00
]
2019-08-31 23:02:41 +00:00
2019-09-01 03:25:10 +00:00
@doc """
Parses a feed from the given data string and MIME type.
An extended set of parsers may also be provided, otherwise the default set (supporting RSS 2.0, Atom, JSON Feed, and RSS-in-JSON) will be used. Parsers are modules that implement the `FeedParser.Parser` behaviour.
"""
2019-08-31 23:18:03 +00:00
@spec parse(data :: String.t(), content_type :: String.t(), parsers :: [module()]) ::
{:ok, feed :: FeedParser.Feed.t()} | {:error, reason :: term()}
def parse(data, content_type, parsers \\ @default_parsers)
def parse(nil, _, _) do
{:error, :no_data}
end
def parse(data, content_type, parsers) when is_binary(data) do
2019-08-31 23:02:41 +00:00
parsers
|> Enum.reduce_while(false, fn parser, acc ->
case parser.accepts(data, content_type) do
{true, result} ->
{:halt, {parser, result}}
_ ->
{:cont, acc}
end
end)
|> case do
{parser, result} ->
parser.parse_feed(result)
false ->
2021-10-03 14:06:06 +00:00
{:error, "no parser matched the given content type ('#{content_type}') and data"}
2019-08-31 23:02:41 +00:00
end
end
end