# `Lather.Mtom.Attachment`
[🔗](https://github.com/awksedgreep/lather/blob/v1.0.49/lib/lather/mtom/attachment.ex#L1)

MTOM attachment data structure and utilities.

This module defines the structure for binary attachments in MTOM messages
and provides utilities for creating, validating, and managing attachments.

## Attachment Structure

An attachment represents a binary file or data that will be transmitted
as part of an MTOM message using XOP (XML-binary Optimized Packaging).

## Examples

    # Create a simple attachment
    attachment = Attachment.new(pdf_data, "application/pdf")

    # Create attachment with custom content ID
    attachment = Attachment.new(image_data, "image/jpeg", content_id: "image001")

    # Validate attachment
    :ok = Attachment.validate(attachment)

# `t`

```elixir
@type t() :: %Lather.Mtom.Attachment{
  content_id: String.t(),
  content_transfer_encoding: String.t(),
  content_type: String.t(),
  data: binary(),
  id: String.t(),
  size: non_neg_integer()
}
```

# `cid_reference`

```elixir
@spec cid_reference(t()) :: String.t()
```

Generates a CID (Content-ID) reference for XOP includes.

## Parameters

  * `attachment` - The attachment

## Returns

  * CID reference (e.g., "cid:attachment123@lather.soap")

## Examples

    cid_ref = Attachment.cid_reference(attachment)
    # "cid:attachment123@lather.soap"

# `content_id_header`

```elixir
@spec content_id_header(t()) :: String.t()
```

Generates a Content-ID header value for the attachment.

## Parameters

  * `attachment` - The attachment

## Returns

  * Content-ID header value (e.g., "<attachment123@lather.soap>")

## Examples

    content_id_header = Attachment.content_id_header(attachment)
    # "<attachment123@lather.soap>"

# `from_file`

```elixir
@spec from_file(
  String.t(),
  keyword()
) :: {:ok, t()} | {:error, term()}
```

Creates an attachment from a file path.

## Parameters

  * `file_path` - Path to the file
  * `options` - Additional options (same as `new/3`)

## Examples

    {:ok, attachment} = Attachment.from_file("document.pdf")
    {:ok, attachment} = Attachment.from_file("image.jpg", content_type: "image/jpeg")

# `from_tuple`

```elixir
@spec from_tuple(tuple()) :: {:ok, t()} | {:error, term()}
```

Converts an attachment tuple to an Attachment struct.

## Parameters

  * `attachment_tuple` - Tuple in format `{:attachment, data, content_type}` or
    `{:attachment, data, content_type, options}`

## Returns

  * `{:ok, attachment}` - Successfully created attachment
  * `{:error, reason}` - If the tuple is invalid

## Examples

    {:ok, attachment} = Attachment.from_tuple({:attachment, data, "application/pdf"})
    {:ok, attachment} = Attachment.from_tuple({:attachment, data, "image/jpeg", [content_id: "img1"]})

# `is_attachment?`

```elixir
@spec is_attachment?(any()) :: boolean()
```

Checks if a parameter value represents an attachment.

## Parameters

  * `value` - The value to check

## Returns

  * `true` if the value is an attachment tuple, `false` otherwise

## Examples

    Attachment.is_attachment?({:attachment, data, "application/pdf"}) # true
    Attachment.is_attachment?("regular string") # false

# `new`

```elixir
@spec new(binary(), String.t(), keyword()) :: t()
```

Creates a new attachment from binary data and content type.

## Parameters

  * `data` - Binary data for the attachment
  * `content_type` - MIME content type (e.g., "application/pdf")
  * `options` - Additional options

## Options

  * `:content_id` - Custom Content-ID (auto-generated if not provided)
  * `:content_transfer_encoding` - Transfer encoding (default: "binary")
  * `:validate` - Whether to validate the attachment (default: true)

## Examples

    attachment = Attachment.new(pdf_data, "application/pdf")

    attachment = Attachment.new(image_data, "image/jpeg",
      content_id: "custom-id-123"
    )

# `validate`

```elixir
@spec validate(t()) :: :ok | {:error, atom()}
```

Validates an attachment structure and content.

## Parameters

  * `attachment` - The attachment to validate

## Returns

  * `:ok` - If the attachment is valid
  * `{:error, reason}` - If the attachment is invalid

## Examples

    :ok = Attachment.validate(attachment)
    {:error, :data_too_large} = Attachment.validate(huge_attachment)

# `xop_include`

```elixir
@spec xop_include(t()) :: map()
```

Creates an XOP Include element for the attachment.

## Parameters

  * `attachment` - The attachment

## Returns

  * Map representing XOP Include element

## Examples

    xop_include = Attachment.xop_include(attachment)
    # %{"xop:Include" => %{"@href" => "cid:attachment123@lather.soap", "@xmlns:xop" => "..."}}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
