wire/privacy/operation.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4// Copyright (c) 2026 2youg1 and the sprawling contributors
5
6//! What `Command::PrivacyOperation` asks for, and the result the host
7//! keeps for it under its `idem` (`crates/wire/spec/Privacy.lean` ยง8-89).
8
9use kernel::{AxError, IdemKey};
10use serde::{Deserialize, Serialize};
11
12use super::answer::PrivacyValue;
13use super::{PrivacyControl, PrivacyFaultCode, PrivacySettlement};
14
15/// Change one host privacy control, or check the operation that has no
16/// conclusion: the payload of `Command::PrivacyOperation`. The city's
17/// listener carries it out on the host, and its result is read back from
18/// [`crate::PrivacyAnswer::outcomes`] under `idem`.
19#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
20#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
21pub struct PrivacyRequest {
22 pub action: PrivacyAction,
23 pub idem: IdemKey,
24}
25
26/// One change the person confirmed on the page. `expected` is the value
27/// the page showed when the person confirmed; the host writes nothing when
28/// its fresh read differs (`crates/sprawling/spec/Privacy/Confirmation.lean`
29/// D58).
30#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
31#[serde(rename_all = "snake_case")]
32#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
33pub enum PrivacyAction {
34 /// Write the control's value over `expected`.
35 Apply {
36 control: PrivacyControl,
37 expected: PrivacyValue,
38 },
39 /// Put back the value this app's latest change of the control found.
40 Restore {
41 control: PrivacyControl,
42 expected: PrivacyValue,
43 },
44 /// The person's check of the operation that has no conclusion:
45 /// `expected` is the value the page showed for its control. Writes
46 /// nothing.
47 Reconcile { expected: PrivacyValue },
48}
49
50/// The result kept for one operation a page sent.
51#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
52#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
53pub struct PrivacyOutcome {
54 pub idem: IdemKey,
55 pub action: PrivacyAction,
56 pub result: PrivacyResult,
57}
58
59/// Where one operation stands.
60#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
61#[serde(rename_all = "snake_case")]
62#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
63pub enum PrivacyResult {
64 /// Accepted and not finished: it waits for an earlier operation, for
65 /// administrator approval, or for its readback.
66 Running,
67 /// `operation` is the history's number for it, never zero.
68 Applied {
69 operation: u64,
70 },
71 Restored {
72 operation: u64,
73 },
74 /// The target already held the control's value; nothing was written
75 /// or recorded.
76 AlreadyWritten,
77 Reconciled {
78 operation: u64,
79 settlement: PrivacySettlement,
80 },
81 /// The change asked for did not happen, or its result is unconfirmed;
82 /// `error` says which and what to do.
83 Refused {
84 code: PrivacyFaultCode,
85 error: AxError,
86 },
87}