#[non_exhaustive]pub enum IslandOp {
Set {
island: Island,
},
Insert {
at: usize,
island: Island,
},
}Expand description
An island edit: the channel that reaches Island payloads, which no other
channel carries (text holds one ISLAND_SLOT per island and nothing
more, lines the LineKind::Island tag, marks neither).
Both ops are value semantics over one island entry, not over the field:
the slot stays put, so every identity anchor in the field’s text survives an
island edit. Without them a table edit lowers to a whole-field install,
which drops every anchor in the field: LineOp::SetContinues’s argument at
the scale of a table.
Removal needs no op: a text delta that deletes a slot drops the backing
entry (Content::apply_text_delta’s cascade). The drop is whole, so
re-landing that island is an IslandOp::Insert carrying the Island
itself, which only the producer that deleted it still holds. A block
island’s line demotes to Para when its slot goes, so re-landing one
re-tags the line too.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Set
Replace the entry island.id names, in place. The id is the target and
the stored value, so an island cannot be renamed through this op: ids are
hash input and stable across edits by contract
(DOCUMENT_STORAGE.md § Island-id determinism). An id no island carries
is ApplyError::UnknownIslandId, never a silent no-op: swallowing it
leaves the store on the old value with the caller believing it committed.
props, island_type and loss all come from the op. Nothing derives
loss from the props: like install, the op stores what the caller hands
it, so a write that changes what markdown can carry restates the class or
carries the stale one forward.
Insert
Insert an island: the ISLAND_SLOT at at and its backing entry in
one op, so a slot never exists without the Island behind it (the
orphan ApplyError::IslandSlotInInsert guards against on the text
channel is unrepresentable here rather than rejected after the fact).
at is a USV position in the text the delta and this bundle’s earlier
island ops left: each insert splices its slot before the next op reads
the text. Slots after a and b of abc therefore go in at 1 and 3,
and of two inserts at one position the later one lands first. The entry
files at its slot-order index in that same frame, so text and island
list agree whatever the emission order; a stale frame misplaces slots
and never errors.
The id is caller-supplied, non-empty, and unique in the field, on an
anchor id’s terms (ApplyError::EmptyIslandId,
ApplyError::IslandIdCollision). Set addresses by id, so a
degenerate or shared id is an island that cannot be edited, or cannot be
told from another. Minting follows DOCUMENT_STORAGE.md § Island-id
determinism: a new island continues the field’s positional sequence,
while re-landing a dropped one carries its original id back. A delete
earlier in the same bundle frees its id here, which is how a
replace-in-place lands as one bundle.
Block islands. The slot alone is an inline island (a slot in a
Para). A block island is that slot alone on its own line under
LineKind::Island, which takes three channels in one bundle: the text
delta inserts the \n, this op inserts the slot, and
LineOp::SetKind tags the line. That order is why island ops run
before line ops: SetKind validates the kind against the text already
on the line, so the slot has to be there first. LineOp::Split cannot
stand in for the delta’s \n: it runs in the later stage.
A slot inserted onto a line whose kind names its content (Code, Rule)
contradicts that kind; normalize demotes the line to Para at the end
of the bundle rather than failing it.