pub enum DriveOperation {
Read,
Create,
Upload,
Edit,
SheetsWrite,
SheetsStructure,
SheetsDelete,
SheetsProtection,
DocsWrite,
}Expand description
A Drive operation this gate can permit or refuse. Reused directly as the
settings-file rule shape (crate::utils::settings::WritePermissionsSettings)
— no separate wire type.
Variants§
Read
List/read/export/download.
Create
Create a new file or folder.
Upload
Upload local content into a new file.
Edit
Replace an existing file’s content.
SheetsWrite
Write cells into an existing Google Sheet via the Sheets API (issue #1589, ADR-0073 §3).
Deliberately not folded into Self::Edit. Every existing
allow: ["edit"] rule was written when drive edit refused every
Google-native document outright, so reusing Edit here would
retroactively upgrade those rules into cell-write permission with no
config change and no re-consent — the exact silent widening this
gate’s default-deny posture exists to prevent.
Since issue #1798 (ADR-0081 §5), also
required (alongside Self::SheetsStructure) for add-pivot-table
— a pivot table is created by updateCells, writing through the
grid with a server-computed rendered extent, which is this
operation’s territory by construction. delete-pivot-table needs
this operation alone.
Since issue #1839 (ADR-0083 §4), also
the clipboard-style paste family — cut-paste/copy-paste with a
value-only --paste-type (values/formula) and paste-data‘s
values/formula types — since each writes ordinary cell content
into a range this crate already lets sheets clear/write reach.
cut-paste additionally requires Self::SheetsStructure whatever
--paste-type names, since it always clears its source’s formats
and merges too; copy-paste/paste-data require it alongside this
operation only for --paste-type normal, per that variant’s doc
comment.
Since issue #1840 (ADR-0083 §1), also
covers auto-fill (autoFill) alone: it writes ordinary cell
content into a range the request names or derives, exactly what
this operation already permits via sheets clear followed by
sheets write of the same range. Provisional on ADR-0083 §5’s
live-verification rule — if a fill is found to carry the source
cells’ formatting, auto-fill moves to the two-operation
composition add-pivot-table uses, alongside Self::SheetsStructure.
Since issue #1841 (ADR-0083 §1), also
required for find-replace. Its range, sheet and all-sheets scopes
replace only cell values or formulas, already covered by sheets write and sheets clear; scope does not create a new permission
boundary within a spreadsheet.
Since issue #1842 (ADR-0083 §3), also
one half of sort-range’s gate, alongside Self::SheetsStructure
— re-gated by issue #1870 after live verification found a sorted row
carries its formatting, notes and data-validation rules with it (see
that variant’s doc comment). It shipped first on this operation
alone, on a values-only reading: it permutes values within a
caller-named range, which a sheets-write grant could already
replace or clear.
Since issue #1843 (ADR-0083 §1),
also one half of text-to-columns’ gate, for the cell content the
split writes — but not the whole of it. ADR-0083 §1 proposed
this operation alone and §5 made that provisional on live
verification; the live run found a split carries the source cell’s
formatting into the spill cells, so §5’s fixed consequence
applies and text-to-columns needs Self::SheetsStructure too,
the two-operation composition add-pivot-table uses.
Since issue #1845 (ADR-0083 §§3, 5),
also one half of randomize-range’s gate, alongside
Self::SheetsStructure, for the cell values a reorder permutes.
ADR-0083 §3 proposed this operation alone and §5 made that
provisional on live verification, same as text-to-columns; the
live run found a reordered row carries its formatting, notes and
data-validation rules with it, so §5’s fixed consequence applies
here too.
Since issue #1940, also one half of set-basic-filter --sort-by’s
gate, alongside Self::SheetsStructure: a basic filter’s sort is
applied by physically reordering the rows, the same permutation as
randomize-range, so it takes the same union (see that variant’s
doc comment).
Since issue #1844 (ADR-0083 §1),
also trim-whitespace: it rewrites cell content in place, which a
sheets write of the same range could already replace outright.
Unlike the reorder verbs above, it stays on this operation alone:
issue #1877’s live check found a trim moves no formatting, and even
rebases rich-text runs to keep them on the characters that remain.
Its sibling verb in that issue, delete-duplicates, takes
Self::SheetsDelete instead — two verbs shipped together under
two different operations, which is the per-verb mapping working as
intended, not a special case.
SheetsStructure
Structurally edit an existing Google Sheet via spreadsheets.batchUpdate
(issue #1613, ADR-0075 §1) — adding,
renaming and inserting rows or columns; since issue #1643
(ADR-0078), cell/border formatting,
merging, auto-resize, column width/row height, data validation,
duplicateSheet, and sheet reorder/hide. Since issue #1795
(ADR-0081 §4), also developer-metadata
management (set-developer-metadata/delete-developer-metadata),
restricted to DOCUMENT visibility — PROJECT-visibility metadata,
which belongs to a different OAuth client, is never reachable
through this surface; since issue #1793
(ADR-0081 §1), conditional formatting
(add-conditional-format/update-conditional-format/
delete-conditional-format); since issue #1796
(ADR-0081 §2), also named-range
add/update/delete: a named range is a label over a region, not grid
data, so removing one leaves every cell’s stored value and formula
text untouched — even though every cell formula referencing the
removed name starts evaluating to #REF!. That
visible-but-not-destructive effect is mitigated, not by a stronger
gate, but by delete-named-range scanning the workbook’s cell
formulas for the name and reporting the count and A1 locations of
every reference before it deletes, in both --dry-run and the real
run; and, since issue #1797
(ADR-0081 §3), charts and slicers
(add-chart/update-chart/delete-chart/add-slicer/
update-slicer/delete-slicer) — including the two deletes, which
destroy an unrecoverable embedded object rather than grid data, and
so join this operation (not Self::SheetsDelete) on the same
“property of the sheet, not the sheet’s data” reasoning as
unmerge-cells/clear-data-validation. None of that later set
destroys grid data either, which is what earns it the same
operation as the original three rather than one of its own.
Since issue #1798 (ADR-0081 §5), also
required (alongside Self::SheetsWrite) for add-pivot-table —
the first capability in the crate resolving two operations
together rather than one. A pivot table is also a named, persistent,
structural feature of a sheet, which is why it needs this operation
too and not SheetsWrite alone.
Since issue #1832 (ADR-0082),
also banded ranges (add-banding/update-banding/delete-banding)
— alternating row/column colors applied to a range, the same
“property of the sheet, not the sheet’s data” reasoning as
unmerge-cells/clear-data-validation; removing one destroys no
grid data.
Since issue #1833 (ADR-0084),
also dimension groups (add-dimension-group/update-dimension-group/
delete-dimension-group) — the collapsible +/- outline over a row
or column span, the same reasoning again; removing a group destroys
no grid data either.
Since issue #1835 (ADR-0085), also
update-sheet-properties — frozen rows/columns, tab color,
right-to-left layout, and hidden gridlines, all per-sheet view state
rather than grid data.
Since issue #1836 (ADR-0086),
also update-workbook-properties — locale, time zone, automatic
recalculation, and iterative calculation. The one capability in this
variant with no sheet target at all, since it acts on the workbook
itself; turning iterative calculation on changes what an unchanged
circular-reference formula elsewhere evaluates to rather than
touching any formula directly, the same shape of value effect
ADR-0081 §2 already accepted here for named-range deletion.
Since issue #1838, also insert-range — the exact inverse of
delete-range’s cell-range half, inserting empty cells into a
sub-rectangle and shifting the existing cells in that column/row
extent right or down. It joins this operation, not
Self::SheetsDelete, because no cell value is discarded: every
shifted cell keeps its content and the vacated cells become empty.
The one asymmetry with delete-range: a cell pushed past the
sheet’s current grid extent by the shift is silently dropped by the
Sheets API, so this capability can lose data at the grid edge even
though it destroys none within it.
Since issue #1837, also moving/resizing an existing chart or slicer
(move-chart/move-slicer, updateEmbeddedObjectPosition) and
setting or clearing a chart’s border colour (update-chart-border,
updateEmbeddedObjectBorder) — the same operation as the rest of
this chart/slicer set (add-chart/update-chart/delete-chart/
add-slicer/update-slicer/delete-slicer), since a move or a
border change discards no data either.
Since issue #1839 (ADR-0083 §4), also
required (alongside Self::SheetsWrite) for cut-paste
unconditionally, and for copy-paste/paste-data when
--paste-type is normal (formats and merges travel with the cell
content) — plus required alone, no Self::SheetsWrite needed,
for copy-paste/paste-data’s presentation-only format type,
which writes nothing this crate treats as a cell value. cut-paste
needs this operation whatever it pastes because the source is
always cleared of its formats and merges too, the same “property of
the sheet, not the sheet’s data” removal unmerge-cells/
clear-data-validation already make under this operation.
Deliberately not folded into Self::SheetsWrite, for the same
reason that one is not folded into Self::Edit. Every existing
allow: ["sheets-write"] rule was written when structural edits were
impossible, so reusing it here would retroactively upgrade those rules
into permission to restructure a workbook with no config change and no
re-consent.
The same argument binds future work: row and sheet deletion must
not later join this variant either, or granting it today would silently
become consent to destroy data tomorrow. Nor may a permission
change — see Self::SheetsProtection, carved out of this same
deferred set for exactly that reason.
Since issue #1843 (ADR-0083 §§1, 5),
also the second half of text-to-columns’ gate, alongside
Self::SheetsWrite. Not because the split is a structural edit
in itself, but because it was measured propagating the source
cell’s formatting into spill cells that had none: a live split of
a bold, pink column left every cell it wrote bold and pink. That is
this operation’s own subject matter, so a sheets-write grant
alone cannot confer it.
Since issue #1845 (ADR-0083 §§3, 5),
also the second half of randomize-range’s gate, alongside
Self::SheetsWrite. Not because a reorder is a structural edit in
itself, but because it was measured carrying a row’s formatting,
notes and data-validation rules with it, and rewriting the
relative references of any formula moved along with it — a live
probe reordering a bold, pink row with a note, a validation rule
and a relative formula moved all four with the row. That is this
operation’s own subject matter, so a sheets-write grant alone
cannot confer it.
Since issue #1870, sort-range needs this operation too, alongside
Self::SheetsWrite — the same live-verification finding as
randomize-range: formatting, notes and data-validation rules
travel with a reordered row, and an in-range relative formula
rewrites to keep pointing at its own row. It shipped first (#1842)
on SheetsWrite alone, before this was measured.
Since issue #1940, set-basic-filter --sort-by resolves this
operation and Self::SheetsWrite — every other filter verb, and
set-basic-filter without --sort-by, still resolves this one
alone (ADR-0081 §1). A basic filter’s sort physically reorders the
filtered range’s rows, the same permutation randomize-range
performs, and the reorder outlives clear-basic-filter; so it takes
randomize-range’s union rather than being treated as view state.
SheetsDelete
Destructively edit an existing Google Sheet via spreadsheets.batchUpdate
(issue #1623, ADR-0077) — deleting a
sheet, a row/column range, or an arbitrary cell range.
Deliberately not folded into Self::SheetsStructure, per the
binding clause on that variant: every existing allow: ["sheets-structure"] rule was written when deletion was impossible,
so reusing it here would retroactively upgrade those rules into
permission to destroy data with no config change and no re-consent.
The same argument binds future work: no other operation should later join this variant without the same re-consent reasoning.
Since issue #1844 (ADR-0083 §2),
also delete-duplicates — the first capability to join this
variant since ADR-0077 defined it, and admitted under exactly the
re-consent reasoning the clause above demands: an operator who
granted sheets-delete consented to having cells removed and
shifted up within a caller-named range by this tool, and
delete-duplicates does just that. Content outside the range
stays in place. It asks for nothing beyond that.
One thing about it is new, and is recorded here rather than
buried in the verb: every other capability under this operation
removes cells the caller named by address, whereas
delete-duplicates removes rows the server selects from the
data — by an equality rule that ignores letter case, formatting and
formulas, and that reaches rows hidden by a filter. A
sheets-delete grant used through this verb therefore deletes
whatever that rule finds. ADR-0083 §2 accepts that as within the
grant’s consent (rows removed from a range this tool was told to
act on) and mitigates it where it belongs — in the verb, which
states the rule in both the preview and the real run rather than
implying the caller chose the rows.
SheetsProtection
Add, change or remove a protected range on an existing Google Sheet
via spreadsheets.batchUpdate (issue #1643,
ADR-0078).
Deliberately not folded into Self::SheetsStructure, and the
reason is different in kind from every other split on this enum: a
protected range is who may edit, not what the sheet contains.
updateProtectedRange can widen the set of editors and
deleteProtectedRange removes a guard someone deliberately placed —
both are permission changes inside the document, closer in spirit to
drive permissions than to any cell or structural write this tool
makes. Folding it into sheets-structure would let a grant issued
for “may reformat/validate/restructure this workbook” silently
double as “may also change who can edit it” — a widening in kind,
not merely in scope, which is why this earns its own operation
rather than joining the set sheets-structure’s own doc comment
just absorbed.
This binds future work too: nothing reachable under this operation
may ever touch a file-level Drive permission (drive permissions
is that surface, and stays the only one).
DocsWrite
Replace or append text in an existing Google Doc via the Docs API (issue #1615, ADR-0076 §2).
Folded into neither Self::Edit nor Self::SheetsWrite, and the
argument runs in both directions. Every allow: ["edit"] rule was
written when drive edit refused every Google-native document
outright — which it still does. Every allow: ["sheets-write"] rule
was written when Docs were unreachable through this tool, and that
operation is lexically about cells, so making it govern prose would
be a lie told by the config vocabulary itself.
This binds future work. A Docs deletion verb must not be folded
into this variant either: a grant issued today for “may replace text”
must not silently become consent to remove content tomorrow. When
deletion is designed it needs its own operation, or explicit
re-consent. Same rule ADR-0075 §1 records for sheets-structure.
Implementations§
Source§impl DriveOperation
impl DriveOperation
Sourcepub const fn ever_requires_lease(self) -> bool
pub const fn ever_requires_lease(self) -> bool
Whether an Allow verdict for this operation is ever backed by a
Drive write lease requirement (issue #1917).
Read never mutates anything, and Create/Upload write into a
new file — there is no existing content for a lease to protect,
and neither engine (create.rs, upload.rs) ever gates on
require_lease; the field appears on their LeasedWrite values
only in test fixtures. Every other operation replaces or otherwise
mutates a target’s existing content and does gate on it via
decided_rule_requires_lease. This is consulted only by
drive permissions check’s diagnostic, to keep it from reporting a
lease requirement an operation could never actually be asked to
satisfy — it does not itself change what any engine enforces.
Trait Implementations§
Source§impl Clone for DriveOperation
impl Clone for DriveOperation
impl Copy for DriveOperation
Source§impl Debug for DriveOperation
impl Debug for DriveOperation
Source§impl<'de> Deserialize<'de> for DriveOperation
impl<'de> Deserialize<'de> for DriveOperation
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Display for DriveOperation
impl Display for DriveOperation
impl Eq for DriveOperation
Source§impl Hash for DriveOperation
impl Hash for DriveOperation
Source§impl PartialEq for DriveOperation
impl PartialEq for DriveOperation
Source§impl Serialize for DriveOperation
impl Serialize for DriveOperation
impl StructuralPartialEq for DriveOperation
Auto Trait Implementations§
impl Freeze for DriveOperation
impl RefUnwindSafe for DriveOperation
impl Send for DriveOperation
impl Sync for DriveOperation
impl Unpin for DriveOperation
impl UnsafeUnpin for DriveOperation
impl UnwindSafe for DriveOperation
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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 moreSource§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> ResetDiscriminant<T> for Twhere
T: Copy,
impl<T> ResetDiscriminant<T> for Twhere
T: Copy,
Source§fn discriminant(&self) -> T
fn discriminant(&self) -> T
Source§impl<T> ToCompactString for Twhere
T: Display,
impl<T> ToCompactString for Twhere
T: Display,
Source§fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
ToCompactString::to_compact_string() Read moreSource§fn to_compact_string(&self) -> CompactString
fn to_compact_string(&self) -> CompactString
CompactString. Read moreSource§impl<T> ToStringFallible for Twhere
T: Display,
impl<T> ToStringFallible for Twhere
T: Display,
Source§fn try_to_string(&self) -> Result<String, TryReserveError>
fn try_to_string(&self) -> Result<String, TryReserveError>
ToString::to_string, but without panic on OOM.