# `SubtitleCue`

A timed caption (WebVTT): when it starts and ends from the start of the media, its end after its start, and its text, written as the cue's timings line and text: `00:00:01.000 --> 00:00:04.000` and a line feed.

[Media and visual](types.md#media-and-visual); not ordered; since Jadpo 0.1.0.

## Make one

Build one from its fields, `SubtitleCue { start: ...  end: ...  text: ... }`.

`text.parse(raw, as: SubtitleCue)` reads one from its text; text that isn't one at all fails `malformed`, such as `"00:00:04.000 --> 00:00:01.000\nBackwards"`, `"00:00:01.000 --> 00:00:04.000\nOne\n\nTwo"` or `"00:00:01.000 --> 00:00:04.000\n"`.

Its parts keep these rules; a value that breaks one fails with the rule's name:

- `start_not_negative`: `start >= 0ms`
- `end_after_start`: `end > start`
- `text_without_arrow`: `text holds no `-->``

## Fields

| Field | Type |
|---|---|
| `start` | [`Duration`](type-duration.md) |
| `end` | [`Duration`](type-duration.md) |
| `text` | `Text` |

## Text, JSON and storage

`text.from` writes its canonical text, the one form `text.parse` reads back. JSON sends an object of its parts.

| Text | JSON |
|---|---|
| `00:00:01.000 --> 00:00:04.000\nNever drink liquid nitrogen.` | `{"start":"PT1S","end":"PT4S","text":"Never drink liquid nitrogen."}` |
| `00:01:05.250 --> 00:01:07.500\n— It will perforate your stomach.\n— You could die.` | `{"start":"PT1M5.25S","end":"PT1M7.5S","text":"— It will perforate your stomach.\n— You could die."}` |
| `100:00:00.000 --> 100:00:00.001\nEnd` | `{"start":"PT100H","end":"PT100H0.001S","text":"End"}` |

It is stored in 3 columns, each named for the field, `_` and its suffix. This is `00:01:05.250 --> 00:01:07.500\n— It will perforate your stomach.\n— You could die.`:

| Column | Type | Holds |
|---|---|---|
| `<field>_start` | `bigint` | `65250` |
| `<field>_end` | `bigint` | `67500` |
| `<field>_text` | `text` | `E'— It will perforate your stomach.\n— You could die.'` |

## Shown to people

`text.format(value, locale:)` shows it to people in their locale.

With `locale: Locale.en_gb`:

| Value | Shown |
|---|---|
| `"00:00:01.000 --> 00:00:04.000\nNever drink liquid nitrogen."` | `"00:00:01.000 --> 00:00:04.000\nNever drink liquid nitrogen."` |
| `"00:01:05.250 --> 00:01:07.500\n— It will perforate your stomach.\n— You could die."` | `"00:01:05.250 --> 00:01:07.500\n— It will perforate your stomach.\n— You could die."` |
| `"100:00:00.000 --> 100:00:00.001\nEnd"` | `"100:00:00.000 --> 100:00:00.001\nEnd"` |

## Operations

It has the contract's own operations: `text.parse`, `text.from`, `text.format`, `json.read`, `json.write` and `==`. It isn't ordered, so `<` and sorting don't take it. [Every standard type meets one contract](../topics/every-standard-type-meets-one-contract.md) says how they work.
