Skip to main content

OpKind

Enum OpKind 

Source
pub enum OpKind {
Show 23 variants SetWorkspaceHead { workspace: String, commit: ContentHash, prev: Option<ContentHash>, }, SetRef { name: String, commit: ContentHash, prev: Option<ContentHash>, }, DeleteWorkspace { workspace: String, }, RequestReview { id: String, target: ContentHash, reviewers: Vec<String>, target_ref: Option<String>, }, AssignReviewers { id: String, reviewers: Vec<String>, }, ArchiveReview { id: String, lapsed: bool, }, SlashApproval { id: String, reviewer: String, reason: String, }, PostVerdict { id: String, reviewer: String, verdict: Verdict, note: String, }, PostComment { id: String, comment: String, author: String, body: String, }, DeleteRef { name: String, prev: Option<ContentHash>, }, RecordProvenance { subject: String, kind: String, body: String, }, CreateChange { id: String, owner: String, workspace: String, base_revision: ContentHash, idempotency_key: String, owner_sig: Option<Witness>, cone: Vec<String>, }, CheckpointChange { id: String, workspace: String, revision: ContentHash, prev_revision: ContentHash, }, ArchiveChange { id: String, workspace: String, prev_revision: ContentHash, owner: String, owner_sig: Witness, }, BindKey { operator: String, key: ContentHash, channel: Option<String>, }, RevokeKey { key: ContentHash, reason: String, }, Vouch { voucher: String, subject: String, note: String, }, WithdrawVouch { voucher: String, subject: String, reason: String, }, CountersignSnapshot { witness: String, snapshot: ContentHash, }, RecordRefSnapshot { snapshot: RefSnapshot, }, ViewedReview { id: String, viewer: String, }, RecordCheck { subject: ContentHash, name: String, status: CheckStatus, evidence: String, reporter: String, target_ref: Option<String>, }, Submit { review: String, name: String, commit: ContentHash, prev: Option<ContentHash>, authorization: Authorization, },
}
Expand description

The view mutations. Head-moving ops carry prev (compare-and-set against the current view) so a stale writer is rejected instead of silently clobbering a concurrent advance — the same discipline the op log itself applies to its head.

Variants§

§

SetWorkspaceHead

Point workspace at commit; prev must equal its current head (None = workspace must not exist yet).

Fields

§workspace: String

Workspace being moved.

§commit: ContentHash

New head commit id.

§prev: Option<ContentHash>

Expected current head (CAS), None to create.

§

SetRef

Point named ref name at commit under the same CAS rule.

Fields

§name: String

Ref name (e.g. "main").

§commit: ContentHash

New target commit id.

§prev: Option<ContentHash>

Expected current target (CAS), None to create.

§

DeleteWorkspace

Remove workspace from the view (its commits stay in the store).

Fields

§workspace: String

Workspace being removed.

§

RequestReview

Open review id on commit target, fanning out to reviewers (additive variant, added for review fan-out; wire-format unchanged). id must not already exist.

An empty reviewers list opens the review unassigned: the requester is not naming their own reviewers, and an OpKind::AssignReviewers op fills the list in later. An unassigned review is never complete() and never approved(), so “ask nobody” cannot read as a pass (D24 layer 5).

Fields

§id: String

Caller-chosen review id (unique per log).

§target: ContentHash

The commit under review.

§reviewers: Vec<String>

Actor names the review fans out to; empty = unassigned.

§target_ref: Option<String>

The ref this review proposes to land on, in the view’s namespaced form <repo>:<refname> (e.g. "choir/choir.git:refs/heads/main"). None = unbound: a review of a commit that names no destination.

Additive field, and the worked example of invariant 1 for an enum variant: default + skip_serializing_if means logs written before this field decode as None and re-serialize byte-identically, so their entry hashes do not move.

This is what per-ref policy conditions on. Without it there is no way to say “reviews landing on main are privilege-bearing” — a review named a commit, and a commit belongs to no branch (D24 layer 5; D23 blast-radius gating).

§

AssignReviewers

Fill in the reviewer list of an unassigned review (additive variant, wire-format unchanged). Assign-once: the review must exist with an empty list, and the new list must be non-empty.

This is the view-level half of D24 layer 5 — “the requester does not choose who reviews them”. Who may assign is admission policy (L2), not view semantics: the daemon accepts this op only from its own key, and picks from an operator-curated pool.

Fields

§id: String

The unassigned review being filled in.

§reviewers: Vec<String>

Actor names the review now fans out to (non-empty).

§

ArchiveReview

Settle review id and drop its bulk (additive variant, wire-format unchanged).

A review’s verdicts, notes and reviewer list are the part that grows without bound; the landing gate reads only (target_ref, target, approved). Archiving keeps that triple and discards the rest, so retention stops being an authorization decision — an approval never silently expires.

Archiving is freezing, not deleting. PostVerdict overwrites a reviewer’s earlier verdict, so approval is not monotonic and a review can go approved then not. Once the verdicts are gone that transition can no longer be computed, so an archived review accepts no further verdicts — and says so, rather than reporting itself absent.

Who may archive is admission policy (L2), like OpKind::AssignReviewers: the daemon accepts it only from its own key, because otherwise archiving would be a way to erase a RequestChanges you did not like.

Fields

§id: String

The review being settled.

§lapsed: bool

Settle an incomplete review as not approved, rather than refusing because it never reached an outcome.

An unanswered review is exactly the kind that accumulates, and it is incomplete by definition — so a pruner that can only archive complete reviews reclaims the ones least likely to pile up. Lapsing is the answer, and it deliberately invents no new outcome: a review nobody answered never got approval, so Archived { approved: false } is the whole truth. The landing gate is unchanged, and there is no new persisted enum to version.

When is not a view question. A pure fold of the log has no clock, so the view cannot decide “abandoned”; the node decides on wall time and this op records the decision, exactly as the reviewer draw is decided node-side and recorded by OpKind::AssignReviewers. Replay reproduces the lapse from the op and never from re-running a timer.

Additive: absent in a payload written before this field existed, which decodes as false — the previous strict behaviour exactly.

§

SlashApproval

Invalidate one reviewer’s approval after a policy or trust finding (additive variant, wire-format unchanged).

The operation is append-only: it never moves a ref back and never erases the original verdict. A review with any slash visibly needs re-review, and its affected operator no longer contributes approval weight to future protected-ref authorization.

Live rows verify that reviewer currently has an approval. Archived rows deliberately no longer retain reviewer detail, so admission accepts this operation only from the node key; the signed operation is the compact authority attestation and replay input.

Fields

§id: String

The review whose approval is invalidated.

§reviewer: String

Reviewer channel whose approval is invalidated.

§reason: String

Operator-visible reason for requiring re-review (non-empty).

§

PostVerdict

Record reviewer’s verdict on review id (additive variant). Only listed reviewers may post; re-posting overwrites the reviewer’s own earlier verdict (re-review after changes).

reviewer is payload data and therefore covered by the author signature; binding it to the submitting key is admission policy (L2), not view semantics.

Fields

§id: String

The review being answered.

§reviewer: String

The responding reviewer (must be in the review’s list).

§verdict: Verdict

The verdict.

§note: String

Free-text rationale (may be empty).

§

PostComment

Append one comment to the discussion on review id (D38).

This is the half D34 deferred: a review page could show what was proposed and what was decided, and had nowhere to put the conversation that produced the decision. Discussion is a persisted operation like any other, so it is sequenced, replayable and append-only rather than a mutable side table.

Three properties live in the fold, and each is load-bearing:

  1. Order is the log’s order. The thread is a Vec appended in fold order, not a map keyed by id, because a total order over a conversation is the one thing a single-writer sequencer offers that a mutable comment table cannot.
  2. comment is the replay defence. seq and parent are assigned after signing (invariant 4), so nothing positional is covered by the author’s signature; the payload carries its own identity instead and the fold refuses an id the review already holds. That is the CAS prev in the only shape a comment can take, since a comment moves no head. The ABA hole prev leaves for refs does not open here: an id is never released, because an archived review accepts no comments at all.
  3. Nothing is ever edited. There is no edit and no delete; a correction is a later comment. Removing one is a question about persisted history rather than about presentation, and it needs its own decision row (D38’s tripwire).

author is payload data and therefore covered by the author signature; binding it to the submitting channel is admission policy (L2), exactly as for OpKind::PostVerdict’s reviewer. Without that binding the log’s author attribution and the view’s comment attribution could disagree, which on a discussion surface means words in somebody else’s name.

Fields

§id: String

The review being discussed.

§comment: String

Caller-chosen comment id, unique within that review. It is the author’s retry identity — resubmitting the same comment is refused rather than duplicated — and the anchor a later reply or reaction would name.

§author: String

The channel making the statement (must be the submitting channel, enforced at admission).

§body: String

The comment text (non-empty).

§

DeleteRef

Remove named ref name under the same CAS rule (additive variant, added for git branch deletion; wire-format unchanged).

Fields

§name: String

Ref being removed.

§prev: Option<ContentHash>

Expected current target (CAS).

§

RecordProvenance

Attach an intent/provenance record — task spec, plan, rationale — to subject (D22 substrate; additive variant, wire-format unchanged). The latest record per (subject, kind) wins in the view; the full history stays in the log.

subject is deliberately not bound to the submitting channel — a shared living spec is written by many agents. Trusting who wrote a record means reading the log entry’s author.

Fields

§subject: String

What the record is about: a workspace name, or any agreed channel (e.g. a repo’s shared spec).

§kind: String

Record type, e.g. "task-spec" or "plan".

§body: String

The record text (stored as-is; an empty body is a valid, visible “withdrawn” state, not a deletion).

§

CreateChange

Create stable logical change id and bind its first active workspace at an immutable base revision (additive variant; existing operation bytes are unchanged).

The change id survives later checkpoints and workspace archival. idempotency_key is scoped to owner; the view rejects a second change using the same pair so a lost create response cannot fork one logical request into two changes.

Fields

§id: String

Stable logical contribution id.

§owner: String

Channel allowed to checkpoint the change (enforced by L2 admission because signatures are not part of the pure view).

§workspace: String

Exclusively bound active workspace.

§base_revision: ContentHash

Exact immutable revision the workspace starts from.

§idempotency_key: String

Retry identity, unique within owner.

§owner_sig: Option<Witness>

Owner signature over the matching CreateAuthorization. Absent only on operations accepted before creation authorization was introduced.

§cone: Vec<String>

Directory prefixes this change declares it works within, in git’s cone spelling ("services/api"). Empty = the whole tree, which is what every change written before this field existed decodes to and is exactly the previous behaviour (invariant 1).

Declared, not enforced here. The fold does not police which paths a commit touches; a cone is a statement about intent that the node can serve a matching partial clone from and that conflicts_for_cone narrows a conflict report against. Making it a hard boundary would need path enforcement in the merge layer, which is a separate decision and a much larger one.

It sits in the signed payload rather than in node-side config for the reason D49 puts a check there: a replayer can then reproduce what the change said it was scoped to, and an operator cannot rewrite it after the fact.

§

CheckpointChange

Publish an immutable revision of an existing change and advance its bound workspace under compare-and-set.

Fields

§id: String

Stable logical contribution id.

§workspace: String

The change’s currently bound workspace.

§revision: ContentHash

Newly published immutable revision.

§prev_revision: ContentHash

Expected current change/workspace revision.

§

ArchiveChange

Archive a stable change’s active workspace under revision CAS. The revision remains addressable on the change after the mutable filesystem surface is detached.

Fields

§id: String

Stable logical contribution id.

§workspace: String

The change’s currently bound workspace.

§prev_revision: ContentHash

Expected current change/workspace revision.

§owner: String

Owner channel that signed the matching ArchiveAuthorization.

§owner_sig: Witness

Signature over the canonical authorization bytes. Admission verifies it before this node-authored operation may land.

§

BindKey

Bind actor key key to the durable operator identity operator (additive variant, wire-format unchanged).

Until now an operator existed only as a prefix convention on a channel name (reviewer_operator) plus a line in a mutable, operator-owned keys file. Both are rewritable without a trace, so “these two keys are the same operator” was an assertion no replay could reproduce. This op puts the assertion in the log, where it is sequenced, append-only, and recoverable at any prefix via View::at.

Two properties make it load-bearing, and both live in the fold:

  1. First binding wins the clock. KeyBinding::bound_at is the sequence of the op that first bound the key, and never moves again — so re-binding to adjust a channel cannot reset accumulated standing.
  2. One key, one operator, for the life of the key. Re-binding a key to a different operator is refused, so whatever position a key accumulates cannot be handed to somebody else.

What this does not establish. Who may author a binding is admission policy (L2), exactly as for OpKind::AssignReviewers and OpKind::SlashApproval. With no admission rule wired, any key can bind any other key under any operator name, and operator is a self-chosen label rather than a verified identity. The fold proves sequence and immutability; it never proves authority.

Fields

§operator: String

The durable operator identity the key is bound to. Non-empty, and free of / so it cannot alias a operator/agent channel prefix and read as two different operators.

§key: ContentHash

The actor key being bound: the content address of its public key, as choir_identity::ActorKey::actor_id produces it.

§channel: Option<String>

The channel name the operator asserts this key speaks as, when it asserts one — the sequenced form of the keys file’s <name> <hex> line.

Constrained so the two available operator answers cannot disagree: reviewer_operator of this channel must equal operator, i.e. the channel is operator itself or operator/<agent>. Without that rule a durable record reading “bob” and a channel prefix reading “alice” would both be live, which is worse than a single wrong answer.

Additive per invariant 1: a payload written before this field existed decodes as None and re-serializes byte-identically, so entry hashes do not move.

§

RevokeKey

Withdraw key’s binding (additive variant, wire-format unchanged).

Append-only and terminal. The binding row stays, so the operator attribution for everything the key already did survives; the key itself can never be bound again. Allowing a rebind would make revocation a formality — revoke, rebind, carry on — so the remedy is a fresh key, the same shape as OpKind::SlashApproval’s “open a new review”.

This is the record a revocation cascade replays over, and the slot a later vouch or bond withdrawal hangs off. It moves no ref and undoes no landed change; like a slash, it constrains what comes next rather than rewriting what came before.

Who may revoke is admission policy (L2), as for OpKind::BindKey.

Fields

§key: ContentHash

The bound key whose binding is withdrawn.

§reason: String

Operator-visible reason for the withdrawal (non-empty).

§

Vouch

Record that one operator vouches for another (D65; additive variant, wire-format unchanged).

This is the edge D24’s Sybil resistance was missing. Key age already orders identities by standing, and it cannot tell a hundred keys one stranger bound from a hundred keys a hundred operators bound: age is a fact about a key, never about anybody’s opinion of it. A vouch is the opinion, sequenced.

Both ends must already be operators this log knows. The fold refuses a voucher or subject with no unrevoked binding, which is what makes the floor replayable rather than one node’s private admission rule: minting an identity to vouch with costs a OpKind::BindKey, and only the node authors those. The same rule bounds the map — at most one edge per ordered pair of bound operators, both drawn from a set the node itself admitted — so no client can grow the view by inventing names (D64).

One edge per (voucher, subject): vouching where an edge already stands is refused, so the pair is its own retry identity, exactly as a comment id is for OpKind::PostComment. Changing the note means withdrawing and vouching again, which is a new statement and dated as one.

It authorizes nothing. No threshold, no score, no path count: nothing in this crate or the daemon reads a vouch to decide anything. That is deliberate rather than unfinished. A number computed from this graph would read as a measurement of trustworthiness while measuring how willing operators are to type each other’s names, and the first thing that number would do is become worth farming.

Who may author one is admission policy (L2), as for OpKind::PostVerdict: the daemon binds voucher to the operator of the signing channel. The fold proves the ends exist and the edge is new; it never proves the voucher signed it.

Fields

§voucher: String

The operator doing the vouching (must be the operator of the submitting channel, enforced at admission).

§subject: String

The operator being vouched for. Never equal to voucher: an identity asserting its own standing is the one statement a Sybil can always make.

§note: String

What the voucher wants a reader to know. May be empty.

§

WithdrawVouch

Withdraw a vouch (D65; additive variant, wire-format unchanged).

The edge leaves the view and both ops stay in the log. That split is the deliberate half: a tombstone row would either make withdrawal terminal, which trust is not, or be overwritten by the next vouch, which makes it a row that says nothing. So a current view answers “who vouches for X now”, and “who used to” is a question for the log — the same division OpKind::DeleteRef makes, where the ref goes and the commits stay.

Withdrawal is not terminal for the pair, unlike OpKind::RevokeKey. Vouching again is admissible and starts a fresh VouchState::at. The revocation argument does not carry over: a rebindable revocation is no revocation, but a withdrawal that could never be reconsidered would make one bad afternoon permanent, and the remedy RevokeKey offers — use a fresh key — has no counterpart when the thing withdrawn is an opinion about somebody else.

Fields

§voucher: String

The operator withdrawing (must be the operator of the submitting channel, enforced at admission).

§subject: String

The operator no longer vouched for.

§reason: String

Operator-visible reason (non-empty). It lives in the log rather than in the view, for the reason above.

§

CountersignSnapshot

One witness’s cosignature over the latest ref-state attestation (D67): “I saw this complete ref-state at this position”.

The unit is D25’s RefSnapshot, never an individual ref, and never an choir_oplog::OpEntry. An entry’s witnesses field is inside the bytes its content hash covers, so a cosignature added after the fact would rewrite the entry and orphan every descendant — in-entry witnessing is therefore synchronous by construction, and D16’s tripwire exists precisely to keep that off the sequencer’s critical path. This is the async branch that row already names as its alternative: an ordinary op, admitted after the snapshot it attests, costing the hot path nothing.

The witness signs in the only way this system has: the op’s own author signature covers (channel, payload), and the payload names the snapshot by content address. No second signature scheme, and nothing new to verify.

Fields

§witness: String

The operator doing the witnessing (must be the operator of the submitting channel, enforced at admission, and never the node whose log this is).

§snapshot: ContentHash

Content address of the snapshot being attested, which must be the latest one the fold admitted. Attesting anything else is the stale-ref-state replay D25 names, so it is refused rather than recorded as a claim about the past.

§

RecordRefSnapshot

Record a signed attestation of the complete ref-state at one log position (D25; additive variant, wire-format unchanged).

This is the object that closes the gap the attestation section of the design notes states: every existing check proves the chain a reader was shown is consistent and authentically authored, none proves another reader was shown the same chain. A snapshot is the unit two readers compare, the record that makes a mirror bundle checkable against the log, the checkpoint truncation needs, and — when D16’s gate opens — the thing a witness cosigns. One object, because those are one question: “what was the whole ref-state at seq N?”.

The fold verifies the claim rather than storing it: admission compares RefSnapshot::refs against the view’s refs and RefSnapshot::at_seq against the fold position, so a snapshot that lies about the log it sits in is refused by every replayer, not just by the node that admitted it. The chain rule (prev_snapshot must name the latest admitted snapshot) makes replaying an old snapshot a chain violation even where the ref map recurs — the ABA shape D26 measured, answered here the same way prev answers it for refs.

Who may record one is admission policy (L2), as for OpKind::AssignReviewers: the daemon accepts it only from its own key. The view enforces truth, not authority.

Fields

§snapshot: RefSnapshot

The snapshot; its detached file projection is these exact canonical bytes, never a second schema.

§

ViewedReview

Record that viewer read review id (a read receipt; additive variant, wire-format unchanged; the backlog).

The receipt is what lets an author distinguish “reviewed and ignored” from “nobody has looked yet”. The fact recorded is the first read per viewer – when this review first got that reader’s attention – so the fold refuses a viewer the review already holds, and that refusal doubles as the replay defence, exactly as a comment id does for OpKind::PostComment: nothing positional is signed, so the payload’s (review, viewer) pair is its own retry identity.

A receipt moves no ref, changes no verdict and carries no authorization weight; it is bulk in OpKind::ArchiveReview’s sense and is dropped with the rest of it.

viewer is payload data covered by the author signature; binding it to the submitting channel is admission policy (L2), exactly as for OpKind::PostVerdict’s reviewer.

Fields

§id: String

The review that was read.

§viewer: String

The channel that read it (must be the submitting channel, enforced at admission).

§

RecordCheck

Record one automated check’s outcome on a commit (D49; additive variant, wire-format unchanged).

The node does not run the check. Executing workflows is containers, secrets, caches and artifacts — the largest surface on the platform and the least differentiated part of it, since every forge already has one. What no forge has is a check result that is ordered against the ref it attests and replayable by someone who trusts none of the parties. So this op carries the verdict and nothing else: any runner, or a person, reports by signing one.

That inversion is what makes it stronger than a status field on a merge gate. A field is mutable and is read at merge time, so “was this green when it landed” decays into “is it green now”. A signed op is append-only and sits at a known sequence, so the question stays decidable forever, and choir log --verify already recomputes the hash and checks the signature.

Re-reporting overwrites the reporter’s own earlier result for the same (subject, name), exactly as OpKind::PostVerdict lets a reviewer re-review. A check that flaps is a check that flaps; the log keeps every report and the view keeps the latest.

reporter is payload data covered by the author signature. Binding it to the submitting channel is admission policy (L2), the same split as reviewer and viewer above.

Fields

§subject: ContentHash

The commit the check ran against.

§name: String

Check name, e.g. "ci/build" (non-empty).

§status: CheckStatus

What the check found.

§evidence: String

Where a human can read the run: a URL, a run id, or empty.

§reporter: String

The channel reporting it (must be the submitting channel, enforced at admission).

§target_ref: Option<String>

The ref this check’s subject is proposed to land on, in the view’s namespaced form <repo>:<refname>. None = unbound.

Present for the same reason OpKind::RequestReview carries one, and it is load-bearing twice: per-ref policy conditions on it, and it is the only thing that lets the ACL narrow a check to a repository. A commit id names no repository, so a check without this field is visible to node-wide readers only — correct, and useless to the repository it belongs to.

§

Submit

Land a reviewed commit on a ref and record why it was allowed (D43; additive variant, wire-format unchanged).

OpKind::SetRef can already move a ref, and the landing gate already runs before it. What the log does not keep is the reason: the gate is evaluated at apply time inside the node’s submission policy against files that are not in the log, so a SetRef on a protected ref records that a merge happened and nothing about what permitted it. This op is the same move with the answer attached.

Three properties live in the fold:

  1. The named review must actually say what the landing claims. It must exist, be live, and name exactly this (name, commit) pair. An authorization citing a review about something else is the failure mode worth refusing.
  2. The authorization is rederived, never trusted. Approvers, approval weight, and the approving owner’s standing verdict are all computed from the view and compared; a mismatch is a rejection. The ACL grant behind an owner basis is the one part no replayer can check, because it lives in an operator file.
  3. It is the sole reason the record outlives the review. OpKind::ArchiveReview discards verdicts, so after archiving the entry bytes are the only surviving answer to “who approved this”. Replay still verifies, because validation runs at this op’s own position — before the archive that comes later.

This op narrows the gate on purpose. The node’s weight check takes the maximum over every review naming (ref, commit); a Submit names one review and is judged on that one, so two half-approved reviews of the same commit cannot pool weight through this path.

It is refused on a ref no rule gates. A node not running the review gate, or a ref outside its protected set, takes an ordinary OpKind::SetRef. Admitting a Submit there would mint an authorization record for a decision nothing examined, which is worse than no record — so Basis has no variant for it and admission says so.

Who may submit one is admission policy (L2). Unlike OpKind::AssignReviewers this one is author-signed: the basis is a node determination, but pressing merge is a human act, and the signature is the only place the log can keep who wanted it. Admission rederives the authorization and refuses any mismatch, so a client that writes its own basis buys a rejection rather than a claim.

Fields

§review: String

The review being landed.

§name: String

Ref name, in the view’s namespaced form (<repo>:<refname>).

§commit: ContentHash

The commit to land, which must be the review’s target.

§prev: Option<ContentHash>

Expected current target (CAS), None to create.

§authorization: Authorization

Why this was allowed.

Trait Implementations§

Source§

impl Clone for OpKind

Source§

fn clone(&self) -> OpKind

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for OpKind

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for OpKind

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for OpKind

Source§

fn eq(&self, other: &OpKind) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for OpKind

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Eq for OpKind

Source§

impl StructuralPartialEq for OpKind

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<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,