# `Feel.Runtime.RangeText`
[🔗](https://github.com/FeeJai/BDM/blob/feel-v0.1.0/apps/feel/lib/feel/runtime/range_text.ex#L1)

Reads the text of a range, as `range(from)` does (DMN 1.6, Table 73, grammar rules 66 and 67; decision D-73).

The text is an interval: a bracket, an endpoint, `..`, an endpoint, and a bracket. `[` is a closed start,
`(` and `]` an open one; `]` is a closed end, `)` and `[` an open one. An endpoint is a **literal**, which is
not an expression that is run: a number (`-5`, `1.5`, `1e3`), a string (`"a"`), an `@` literal
(`@"2020-01-01"`), or `date`, `time`, `date and time` or `duration` called on one string
(`date("2020-01-01")`). A name, an operation, a call of anything else and `null` are not endpoints, so no
expression is evaluated and nothing of the run is read.

| The text | The range |
| -------- | --------- |
| `[18..21)` | the interval, as `[18..21)` is |
| `[2..)`, `(2..[` | `>= 2` and `> 2`: the end is not there, and its bracket must be open |
| `(..2)`, `(..2]`, `]..2]` | `< 2` and `<= 2`: the start is not there, and its bracket must be open |
| `[..2]`, `[1..]`, `[..]`, `""`, `[1..2`, `>= 10` | none: the text is not a range |
| `[1.."b"]`, `[1..@"2020-01-01"]` | none: the endpoints are of kinds that are not one |
| `[3..1]` | none: the start is after the end (section 10.3.2.7). `[1..1]` and `(1..1)` are ranges |

The interval is the value that the literal `[18..21)` is (`Feel.Runtime.RangeLiteral.build/4`). A range with an
end that is not there is the one that the test `>= 2` is (`build_prefix/2`), as the specification's examples have
it (`range("[2..)")` is `>=2`), and not the interval `[2..null)`, which is not equal to it (D-61).

The text is read with the lexer and the parser of the expressions, so the white space around the parts, the
escapes of a string and the forms of a number are those of FEEL. A text that is not a range is a diagnostic
with the code `:argument_out_of_domain`, and the reason.

An endpoint that is a time or a date and time is read as the extensions that are on spell it (D-81):
`[@"13:30"..@"14:00"]` and `[time("13:30")..time("14:00")]` are ranges of times where `:camunda` is on, with the
`:info` `:temporal_spelling` reported for each text, and the error of the specification where it is not.

    iex> env = Feel.Runtime.Env.new()
    iex> {:ok, range} = Feel.Runtime.RangeText.parse(~s|[18..21)|, env)
    iex> {range.start, range.end, range.start_included, range.end_included}
    {Decimal.new(18), Decimal.new(21), true, false}
    iex> {:ok, range} = Feel.Runtime.RangeText.parse(~s|(..2)|, env)
    iex> {range.start, range.end, range.operator}
    {nil, Decimal.new(2), :lt}
    iex> {:error, diagnostic} = Feel.Runtime.RangeText.parse(~s|[3..1]|, env)
    iex> diagnostic.details.reason
    "the start is after the end"

# `parse`

```elixir
@spec parse(String.t(), Feel.Runtime.Env.t()) ::
  {:ok, Feel.Value.Range.t()}
  | {:ok, Feel.Value.Range.t(), Feel.Runtime.Env.t()}
  | {:error, Feel.Diagnostic.t()}
```

Reads the text of a range. `{:error, diagnostic}` for a text that is not one, and `{:ok, range, env}` for a range
whose reading reported something (the spelling of an endpoint, D-81): `env` is the one given, with it.

---

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