Skip to main content

Workbook

Struct Workbook 

Source
pub struct Workbook { /* private fields */ }
Expand description

The engine’s public facade: one open workbook.

Write with Workbook::handle_action; read through the Worksheet views from get_sheet_by_idx / _by_name / _by_id. Rows, columns and sheet indices are 0-based throughout. Methods that take a sheet_idx resolve it against the current tab order at call time.

Implementations§

Source§

impl Workbook

Source

pub fn get_block_op_for_payloads(&self) -> Vec<BlockOpForPayload>

The payload → operation table. Static; fetch once and cache.

Source

pub fn get_block_op_policies( &self, sheet_idx: usize, block_id: usize, ) -> Result<Vec<BlockOpPolicy>, Error>

What a block declares for every operation, in a fixed order.

Source§

impl Workbook

Source

pub fn get_defined_names(&self) -> Vec<DefinedNameInfo>

Every defined name, ordered case-insensitively by name.

Source§

impl Workbook

Source

pub fn duplicate_block_keys(&self) -> Vec<DuplicateBlockKey>

Every duplicated row key in the workbook, ordered by sheet, then block, then key, so two calls on an unchanged workbook read the same.

Empty keys are not reported: a blank key cell is what an inserted row starts life with, and it is unaddressable rather than silently wrong. A block with no schema has no key column and is skipped.

Source§

impl Workbook

Source

pub fn get_enum_sets(&self) -> Vec<EnumSetInfo>

Every enum set in the workbook, ordered by id so two reads of an unchanged workbook agree.

Source§

impl Workbook

Source

pub fn check_field_validation( &mut self, sheet_idx: usize, row: usize, col: usize, proposed: String, ) -> Result<FieldValidationVerdict, Error>

Whether writing proposed into the cell at (row, col) would break its field’s validation rule.

Returns has_rule: false — never an error — for every cell that is not a validated block cell: cells outside a block, fields with no rule, and rows whose shadow has not been installed yet. A caller gating a write wants one question answered, and “there is nothing to check here” is an answer, not a failure.

Source§

impl Workbook

Source

pub fn predict_fill( &self, sheet_idx: usize, src: FillRange, dst: FillRange, ) -> Result<Vec<CellInput>, Error>

Predict the contents of a fill-handle drag.

src is the selected source block; dst is the (disjoint) block the user dragged over. Returns one CellInput per target cell. The caller is expected to wrap them in a single transaction.

Source§

impl Workbook

Source

pub fn pivot_plan( &self, sheet_idx: usize, block_id: usize, ) -> Result<PivotPlan, Error>

Compute the shape the pivot block block_id should have.

Read-only. The caller applies it as one transaction — grow, write the keys, bind, shrink — in that order, for the reasons pinned by the reshape tests in api/test.rs; design/block-pivot.md §6.

Errors when the block is not a pivot, when its recipe names a field the source does not have, or when a dimension has more distinct values than a pivot can usefully show.

Source

pub fn pivot_excel_note( &self, sheet_idx: usize, block_id: usize, ) -> Result<PivotExcelNote, Error>

Why this pivot could NOT be saved as a real Excel pivot table, or None when it can.

The saver already decides this every time a file is written; asking it here means a host can find out BEFORE building something, rather than discovering after the fact that the file quietly degraded to a grid of numbers. Ok(None) for a block that is not a pivot at all.

Source

pub fn pivot_plan_for( &self, sheet_idx: usize, source_block: usize, spec: &PivotSpecParts, ) -> Result<PivotPlan, Error>

The shape a pivot over source WOULD have, for a recipe that no block carries yet.

Exists so creating a pivot can be a single transaction — and therefore a single undo. Without it a host would have to create the block, ask what shape it should be, and reshape it, leaving an empty declared pivot as an intermediate state and two steps to undo. The distinct values depend only on the source and the recipe, never on the block, so the question is well-formed before the block exists.

current_* come back empty, so everything the recipe implies is reported as missing.

Source§

impl Workbook

Source

pub fn get_block_sort_order( &self, sheet_idx: usize, block_id: usize, field: &str, asc: bool, ) -> Result<BlockSortOrder, Error>

Compute the row/column order that sorts a block by the field named field, ascending when asc is true. Read-only; the caller applies the result via a ReorderBlockLines transaction.

Errors if the block is a random-schema block (no fields), if the field name is unknown, or if the sheet/block cannot be found.

Source§

impl Workbook

Source

pub fn new() -> Workbook

Create an empty workbook.

Source

pub fn handle_action(&mut self, action: EditAction) -> ActionEffect

Execute the EditAction. See Controller::handle_action for the contract: never panics, rejections come back in the effect. On top of that, re-syncs conditional-formatting shadows for the cells touched.

Source

pub fn get_sheet_name_by_idx(&self, idx: usize) -> Result<String, Error>

Name of the sheet at tab position idx; errors when out of range.

Source

pub fn handle_action_in_temp_status( &mut self, action: PayloadsAction, ) -> ActionEffect

Execute the EditAction on the temp branch. Subsequent calls accumulate on the same branch until commit_temp_status or clean_temp_status is called.

Source

pub fn commit_temp_status(&mut self)

Keep the temp branch and record it as one undo step. No-op without one.

Source

pub fn clean_temp_status(&mut self)

Discard the temp branch, restoring the state it forked from. No-op without one.

Source

pub fn toggle_status(&mut self, _use_temp: bool)

No-op, kept for API compatibility.

Source

pub fn is_in_temp_mode(&self) -> bool

Whether a temp branch is currently active. The branch is a single workbook-wide slot, so a caller that is about to open one (a dry run, a goal-seek probe) must ask first: opening on top of someone else’s branch accumulates into it, and discarding afterwards throws their work away.

Source

pub fn batch_get_cell_info_by_id( &self, ids: Vec<SheetCellId>, ) -> Result<Vec<CellInfo>, Error>

Workbook::get_cell_info_by_id for many cells; the first failure fails the whole call.

Source

pub fn batch_get_cell_coordinate_with_sheet_by_id( &self, ids: Vec<SheetCellId>, ) -> Result<Vec<CellCoordinateWithSheet>, Error>

Current sheet index and position of each cell, e.g. to locate the cells an ActionEffect reports. Fails on the first id that no longer resolves (a deleted cell or sheet).

Source

pub fn get_cell_info_by_id(&self, id: SheetCellId) -> Result<CellInfo, Error>

Read a cell by stable ids.

Source

pub fn from_file(buf: &[u8], book_name: String) -> Result<Workbook, Error>

Create a workbook from a .xlsx file. The loaded state (with its validation and conditional-formatting shadows) is the undo baseline.

Source

pub fn get_app_data(&self) -> Vec<AppData>

Host/craft data stored in the file alongside the workbook. It is a side channel: not part of undo/redo.

Source

pub fn set_app_data(&mut self, app_data: Vec<AppData>)

Replace all app data (not undoable). Saved with the next save.

Source

pub fn get_cell_list_validation( &self, sheet_idx: usize, row: usize, col: usize, ) -> Option<ListValidation>

List-type data-validation options for a cell, or None if the cell is not covered by a list validation. Inline literal lists come back as ListValidation::Inline(values) ready to use; range / named references come back as ListValidation::Reference(raw) for the caller to resolve via its own cell reads. Only list validations are surfaced — this is the read path douyoushu uses to infer enum inputs.

Source

pub fn get_cell_enum_options( &self, sheet_idx: usize, row: usize, col: usize, ) -> Option<Vec<String>>

Flattened, wasm-friendly form of Workbook::get_cell_list_validation: the enum option set for a cell, or None if it has no list validation. Inline literal lists return their values; a range/named reference returns None (the caller can’t use it as a fixed set without resolving cells). Kept simple so it crosses the wasm boundary as Option<Vec<String>>.

Source

pub fn save(&self) -> Result<Vec<u8>, Error>

Save, keeping block formulas in their readable named form.

Source

pub fn save_with_format(&self, format: FormulaFormat) -> Result<Vec<u8>, Error>

Save, choosing how block formulas are written. Use FormulaFormat::Coordinates for a file Excel has to recalculate.

Source

pub fn undo(&mut self) -> bool

Like handle_action(EditAction::Undo) but without the conditional-formatting re-sync that path does. Returns whether anything changed.

Source

pub fn redo(&mut self) -> bool

Redo counterpart of Workbook::undo, with the same caveat.

Source

pub fn clear_history(&mut self)

Clear the undo/redo history, keeping the current state as the baseline. Nothing is reverted; only the history is dropped.

Source

pub fn save_checkpoint( &mut self, label: String, description: Option<String>, ) -> usize

Snapshot the current workbook state under label. Overwrites any existing checkpoint with the same label. Returns the number of checkpoints currently stored after the save.

Source

pub fn delete_checkpoint(&mut self, label: &str) -> bool

Drop a named checkpoint. Returns true if it existed.

Source

pub fn list_checkpoints(&self) -> Vec<CheckpointMeta>

Enumerate all checkpoints, newest first. Returns just labels and descriptions — the bulky Status snapshot stays inside the manager.

Source

pub fn handle_async_calc_results( &mut self, tasks: Vec<Task>, results: Vec<Result<String, AsyncErr>>, ) -> ActionEffect

Feed back results for ActionEffect::async_tasks, paired by position. Mismatched lengths are rejected with StatusCode::Err(1) (and no error_message).

Source

pub fn get_all_sheet_info(&self) -> Vec<SheetInfo>

Every sheet, hidden ones included, in tab order.

Source

pub fn get_formula_function_names(&self) -> Vec<String>

Every distinct formula function name used across the whole workbook (cell formulas + defined names), read from the parsed ASTs — no re-parsing of formula text. Names are uppercased as stored at parse time (_XLFN./_XLWS. prefixes are kept as written), sorted and deduped. Hosts use this to detect which functions a workbook relies on.

Source

pub fn get_cell_positioner(&self, sheet: u16) -> RefCell<CellPositioner<1000>>

The per-sheet cache of row/column start offsets that Worksheet position queries share. Created on first use and never invalidated.

Source

pub fn get_block_values( &self, sheet_id: u16, block_id: usize, row_ids: &[u32], col_ids: &[u32], ) -> Result<Vec<String>, Error>

Plain-text values of block cells, one per (row_ids[i], col_ids[i]) PAIR (zipped, not a cross product; the shorter list wins). Ids are the block’s own line ids. A missing cell reads as "".

Source

pub fn get_sheet_by_name(&self, name: &str) -> Result<Worksheet<'_>, Error>

Exact (case-sensitive) name lookup.

Source

pub fn get_sheet_idx_by_id(&self, sheet_id: u16) -> Result<usize, Error>

Current tab position of a sheet; errors for a deleted sheet.

Source

pub fn get_sheet_by_id(&self, sheet_id: u16) -> Result<Worksheet<'_>, Error>

A view of the sheet with this id. The id is NOT validated: an unknown or deleted id still returns Ok, and the view’s reads fail later. Check with get_sheet_idx_by_id first if that matters.

Source

pub fn get_sheet_idx_by_name(&self, name: &str) -> Result<usize, Error>

Source

pub fn get_sheet_by_idx(&self, idx: usize) -> Result<Worksheet<'_>, Error>

A view of the sheet at tab position idx.

Source

pub fn get_sheet_count(&self) -> usize

Number of sheets, hidden ones included.

Source

pub fn get_version(&self) -> u32

A monotonic counter bumped on every committed write, undo and redo — the controller’s revision, NOT ActionEffect::version. Readers snapshot it to detect concurrent modification (optimistic concurrency). Temp-branch writes and Recalc do not bump it.

Source

pub fn check_formula(&self, f: String) -> bool

Whether f is a syntactically valid formula. Unlike most of the API it expects the leading = (surrounding whitespace allowed). Lexing only: unknown functions, sheets and names still pass.

Source

pub fn get_all_block_fields(&self) -> Result<Vec<BlockField>, Error>

Every field_id assigned to a block line (via BlockLineNameFieldUpdate), across all sheets.

Source

pub fn get_all_blocks( &self, sheet_idx: Option<usize>, sheet_id: Option<u16>, ) -> Result<Vec<BlockInfo>, Error>

Enumerate blocks across the workbook.

Scope selection:

  • sheet_id == Some(id) → only that sheet
  • sheet_idx == Some(idx) → resolve to sheet_id, then that sheet
  • both None → every sheet

If both are set, sheet_id wins (more specific).

Source

pub fn get_block_modify_info( &self, sheet_idx: usize, block_id: usize, ) -> Result<BlockModifyInfo, Error>

Returns the owner and modify policy of a block. Used by the frontend validate hook to gate writes.

Source

pub fn may_modify_block( &self, sheet_idx: usize, block_id: usize, op: BlockOp, actor: &BlockActor, ) -> Result<bool, Error>

Whether actor may perform op on this block.

The engine cannot enforce this itself — a payload carries no trace of who prompted it — so this is the question a host asks before it lets an edit through. Answering it here keeps every host, and the craft runtime, agreeing on what a policy means.

Source

pub fn get_available_block_id(&self, sheet_idx: usize) -> Result<usize, Error>

A block id not yet used on this sheet, for CreateBlock.

Source

pub fn get_shadow_cell_id( &mut self, sheet_idx: usize, row_idx: usize, col_idx: usize, kind: ShadowKind, ) -> Result<SheetCellId, Error>

The ephemeral “shadow” cell of kind attached to a cell, allocating the id on first request (hence &mut). Shadow cells hold derived formulas (validation verdicts, conditional-format matches) and are read like any other cell.

Source

pub fn get_shawdow_cell_ids( &mut self, sheet_idx: usize, row_idx: Vec<usize>, col_idx: Vec<usize>, kind: ShadowKind, ) -> Result<Vec<SheetCellId>, Error>

Workbook::get_shadow_cell_id for (row_idx[i], col_idx[i]) pairs. The two lists must be the same length.

Source

pub fn get_shadow_info_by_id( &self, shadow_id: u64, ) -> Result<ShadowCellInfo, Error>

A shadow cell’s value plus the on-sheet rectangle of the cell it shadows (same units as Worksheet::get_cell_position).

Source

pub fn check_bind_block( &mut self, sheet_idx: usize, block_id: usize, row_count: usize, col_count: usize, ) -> Result<u16, Error>

Resolve sheet_idx and check that a row_count x col_count schema fits in the block.

Source

pub fn get_cell_id_by_block_ref( &self, ref_name: &str, key: &str, field: &str, ) -> Result<SheetCellId, Error>

Resolve a (refName, key, field) triple to the concrete cell in a block-bound table. Mirrors how the BLOCKREF formula resolves at evaluation time:

  1. refName → (sheetId, blockId) via the schema manager’s ref map
  2. enumerate the block’s key cells and find the one whose value matches key
  3. ask the schema to convert (keyCellId, field) → BlockCellId

Returns the BlockCell wrapped in a SheetCellId for direct use with e.g. cell-changed subscriptions or batch reads.

Source

pub fn export_block_data( &self, ref_name: &str, key_filter: Option<Vec<String>>, field_filter: Option<Vec<String>>, ) -> Result<Vec<BlockDataRow>, Error>

Export a block’s data as a row-per-key, column-per-field matrix of values.

  • ref_name: the block’s bound ref name.
  • key_filter: when Some, keep only rows whose key cell’s string value is in the list (order follows the block’s keys, not the filter); when None, every key row is returned.
  • field_filter: when Some, keep only these fields, in the schema’s field order; when None, every field is returned.

Columns follow the same order as get_all_fields(ref_name) (filtered), so the host can pair each column with that field list and the key index it already holds — no metadata is duplicated here.

Source

pub fn get_temp_status_changes(&self) -> Result<TempStatusDiff, Error>

Snapshot of every cell whose value differs between the active temp branch and the committed (fork) status. Used by the host’s diff layer to drive its overlay without needing JS-side snapshot/compare logic. Returns an empty diff when no temp branch is currently active.

Position (row, col) reflects the current sheet coordinates in the temp branch — block inserts may have shifted earlier rows since the fork point. Cells whose CellId exists in temp but not in main (or vice versa) are skipped here; for the moment they surface as structural changes which a future revision can add to the diff.

Source

pub fn calc_condition( &mut self, sheet_idx: usize, f: String, ) -> Result<bool, Error>

Evaluate a formula (with its leading =) as a condition on this sheet and return its truthiness; an error result, or a bad sheet_idx, is Err.

Read-only from the caller’s point of view: the formula is evaluated in a scratch ephemeral cell and the workbook is then put back exactly as it was — an open temp branch survives, and revision does not move.

Source

pub fn get_worksheet_id(&self, sheet_idx: usize) -> Result<u16, Error>

Get the worksheet id by its index.

It is not recommended to use this function because worksheet id is an internal conception. Use this only when you know what you are doing.

Trait Implementations§

Source§

impl Default for Workbook

Source§

fn default() -> Workbook

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more