# `Vize.Diagnostic`
[🔗](https://github.com/elixir-volt/vize_ex/blob/v0.17.1/lib/vize/diagnostic.ex#L1)

Structured diagnostic emitted by Vize.

`to_code_diagnostic/2` converts one to Elixir's `t:Code.diagnostic/1` shape,
which editors, `Mix.Task.Compiler`, and tools such as OXC and Volt share.

# `input`

```elixir
@type input() :: %{
  optional(:code) =&gt; atom() | String.t() | nil,
  :message =&gt; String.t(),
  optional(:location) =&gt; Vize.SourceRange.input() | Vize.SourceRange.t() | nil,
  optional(:loc) =&gt; Vize.SourceRange.input() | Vize.SourceRange.t() | nil,
  optional(:start) =&gt; Vize.SourceLocation.input() | nil,
  optional(:end) =&gt; Vize.SourceLocation.input() | nil,
  optional(:severity) =&gt; :error | :warning,
  optional(:recoverable?) =&gt; boolean(),
  optional(:recoverable) =&gt; boolean()
}
```

# `t`

```elixir
@type t() :: %Vize.Diagnostic{
  code: atom() | String.t() | nil,
  location: Vize.SourceRange.t() | nil,
  message: String.t(),
  recoverable?: boolean(),
  severity: :error | :warning
}
```

# `new`

```elixir
@spec new(input() | t() | String.t()) :: t()
```

# `shift`

```elixir
@spec shift({pos_integer(), pos_integer()}, {pos_integer(), pos_integer()}) ::
  {pos_integer(), pos_integer()}
```

Shifts a `{line, column}` position in a source Vize was given to the file it
came from, whose content starts at `origin`.

# `to_code_diagnostic`

```elixir
@spec to_code_diagnostic(
  t(),
  keyword()
) :: Code.diagnostic(:error | :warning)
```

Converts a diagnostic to Elixir's `t:Code.diagnostic/1` shape.

## Options

  * `:file` — the file the diagnostic belongs to
  * `:origin` — `{line, column}` where the source Vize was given starts in
    that file, such as a `<template>` block's content in an SFC, so
    positions point into the file (default: `{1, 1}`)

---

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