From b875d6677437364c77fd1f660f8f62fe2fb66e53 Mon Sep 17 00:00:00 2001 From: Moises Macia Date: Tue, 17 Feb 2026 22:43:26 +0000 Subject: [PATCH] new structs to fetch, results and session --- lib/feed_reader/fetch.ex | 21 +++++++++++++++++++++ lib/feed_reader/parse_result.ex | 12 ++++++++++++ lib/feed_reader/remote_result.ex | 18 ++++++++++++++++++ lib/feed_reader/session.ex | 24 ++++++++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 lib/feed_reader/fetch.ex create mode 100644 lib/feed_reader/parse_result.ex create mode 100644 lib/feed_reader/remote_result.ex create mode 100644 lib/feed_reader/session.ex diff --git a/lib/feed_reader/fetch.ex b/lib/feed_reader/fetch.ex new file mode 100644 index 0000000..a63a084 --- /dev/null +++ b/lib/feed_reader/fetch.ex @@ -0,0 +1,21 @@ +defmodule FeedReader.Fetch do + @moduledoc """ + HTTP metadata for a completed remote feed fetch. + + The checksum is calculated from the decoded response body. A fetch is only + present on remote results and sessions; local parsing does not invent HTTP + metadata. + """ + + @type t :: %__MODULE__{ + etag: String.t() | nil, + checksum: String.t() | nil, + final_url: String.t() | nil, + status: pos_integer() | nil + } + + defstruct etag: nil, + checksum: nil, + final_url: nil, + status: nil +end diff --git a/lib/feed_reader/parse_result.ex b/lib/feed_reader/parse_result.ex new file mode 100644 index 0000000..5198c7b --- /dev/null +++ b/lib/feed_reader/parse_result.ex @@ -0,0 +1,12 @@ +defmodule FeedReader.ParseResult do + @moduledoc "A bounded collection of normalized data from a local source." + + alias FeedReader.{Feed, Item} + + @type t :: %__MODULE__{ + feed: Feed.t(), + items: [Item.t()] + } + + defstruct feed: nil, items: [] +end diff --git a/lib/feed_reader/remote_result.ex b/lib/feed_reader/remote_result.ex new file mode 100644 index 0000000..8c21487 --- /dev/null +++ b/lib/feed_reader/remote_result.ex @@ -0,0 +1,18 @@ +defmodule FeedReader.RemoteResult do + @moduledoc """ + A bounded collection of normalized data and metadata from a remote fetch. + + The result owns no temporary file after collection completes. Its `fetch` + field contains the HTTP metadata needed by the caller instead. + """ + + alias FeedReader.{Feed, Fetch, Item} + + @type t :: %__MODULE__{ + feed: Feed.t(), + items: [Item.t()], + fetch: Fetch.t() + } + + defstruct feed: nil, items: [], fetch: nil +end diff --git a/lib/feed_reader/session.ex b/lib/feed_reader/session.ex new file mode 100644 index 0000000..f3976b8 --- /dev/null +++ b/lib/feed_reader/session.ex @@ -0,0 +1,24 @@ +defmodule FeedReader.Session do + @moduledoc """ + A one-pass event stream over a feed. + + Remote sessions own the temporary source used by the event stream and must + be closed by callers in an `after` block when enumeration is not completed. + `FeedReader.close/1` is idempotent. Local sessions have no HTTP metadata and + therefore set `fetch` to `nil`; their caller-owned source is never removed. + """ + + alias FeedReader.Fetch + + @type event :: + {:feed, FeedReader.Feed.t()} + | {:item, FeedReader.Item.t()} + | {:error, term()} + + @type t :: %__MODULE__{ + events: Enumerable.t(), + fetch: Fetch.t() | nil + } + + defstruct events: nil, fetch: nil +end