Traversal utilities for %Plover.Response.BodyStructure{} trees.
Provides functions to explore MIME message structures, find parts by type, list attachments, and extract metadata like charset and encoding.
Example
# Fetch body structure
{:ok, [msg]} = Plover.fetch(conn, "1", [:body_structure])
bs = msg.attrs.body_structure
# Find the text/plain part
[{section, part}] = Plover.BodyStructure.find_parts(bs, "text/plain")
# Get charset and encoding for decoding
charset = Plover.BodyStructure.charset(part) # "UTF-8"
encoding = Plover.BodyStructure.encoding(part) # "QUOTED-PRINTABLE"
# List attachments
attachments = Plover.BodyStructure.attachments(bs)
# [%{section: "2", filename: "report.pdf", type: "APPLICATION/PDF", ...}]
Summary
Functions
List attachments in the message.
Get the charset from a body structure's params.
Get the content-transfer-encoding from a body structure.
Find parts matching a MIME type pattern.
Flatten a body structure tree into a list of {section_path, part} tuples.
Get a part by its section path (e.g., "1.2").
Functions
@spec attachments(Plover.Response.BodyStructure.t()) :: [map()]
List attachments in the message.
A part is considered an attachment if its disposition is "ATTACHMENT"
(case-insensitive), or if it has a filename in disposition or body params
and is not "INLINE".
Returns a list of maps with keys: :section, :filename, :type, :size, :encoding.
@spec charset(Plover.Response.BodyStructure.t()) :: String.t()
Get the charset from a body structure's params.
Looks for the "CHARSET" key (case-insensitive). Returns "US-ASCII"
as the default per RFC 2046.
@spec encoding(Plover.Response.BodyStructure.t()) :: String.t()
Get the content-transfer-encoding from a body structure.
Returns "7BIT" as the default per RFC 2045.
@spec find_parts(Plover.Response.BodyStructure.t(), String.t()) :: [ {String.t(), Plover.Response.BodyStructure.t()} ]
Find parts matching a MIME type pattern.
Supports exact matches ("text/plain") and wildcard subtypes ("text/*").
Matching is case-insensitive. Returns {section_path, part} tuples.
@spec flatten(Plover.Response.BodyStructure.t()) :: [ {String.t(), Plover.Response.BodyStructure.t()} ]
Flatten a body structure tree into a list of {section_path, part} tuples.
Only returns leaf parts (not multipart containers). Section paths follow RFC 9051 rules:
- Single-part message:
"" - Multipart children:
"1","2","3"(1-indexed) - Nested multipart:
"1.1","1.2"(dot-separated)
@spec get_part(Plover.Response.BodyStructure.t(), String.t()) :: {:ok, Plover.Response.BodyStructure.t()} | :error
Get a part by its section path (e.g., "1.2").
Returns {:ok, part} or :error if the path is invalid.