1use std::fmt;
13use std::str::FromStr;
14
15use schemars::JsonSchema;
16use serde::{Deserialize, Serialize};
17
18#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
19#[error("unknown {kind} `{value}`")]
20pub struct UnknownDocumentValue {
21 pub kind: &'static str,
22 pub value: String,
23}
24
25macro_rules! wire_enum {
26 ($name:ident, $kind:literal, { $($variant:ident => $wire:literal),+ $(,)? }) => {
27 impl $name {
28 pub const ALL: &'static [Self] = &[$(Self::$variant),+];
29
30 #[must_use]
31 pub const fn as_str(self) -> &'static str {
32 match self {
33 $(Self::$variant => $wire),+
34 }
35 }
36 }
37
38 impl fmt::Display for $name {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 f.write_str(self.as_str())
41 }
42 }
43
44 impl FromStr for $name {
45 type Err = UnknownDocumentValue;
46
47 fn from_str(s: &str) -> Result<Self, Self::Err> {
48 match s {
49 $($wire => Ok(Self::$variant),)+
50 other => Err(UnknownDocumentValue {
51 kind: $kind,
52 value: other.to_owned(),
53 }),
54 }
55 }
56 }
57 };
58}
59
60#[derive(
61 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, JsonSchema,
62)]
63#[serde(rename_all = "snake_case")]
64pub enum AccessLevel {
65 View,
66 Comment,
67 Edit,
68 Share,
69 Own,
70}
71
72wire_enum!(AccessLevel, "access level", {
73 View => "view",
74 Comment => "comment",
75 Edit => "edit",
76 Share => "share",
77 Own => "own",
78});
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
85#[serde(rename_all = "snake_case")]
86pub enum DocumentAction {
87 View,
88 Comment,
89 Edit,
90 Share,
91 Own,
92 Create,
93 Delete,
94}
95
96wire_enum!(DocumentAction, "document action", {
97 View => "view",
98 Comment => "comment",
99 Edit => "edit",
100 Share => "share",
101 Own => "own",
102 Create => "create",
103 Delete => "delete",
104});
105
106impl DocumentAction {
107 #[must_use]
108 pub const fn required_level(self) -> AccessLevel {
109 match self {
110 Self::View => AccessLevel::View,
111 Self::Comment => AccessLevel::Comment,
112 Self::Edit | Self::Create => AccessLevel::Edit,
113 Self::Share => AccessLevel::Share,
114 Self::Own | Self::Delete => AccessLevel::Own,
115 }
116 }
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
120#[serde(rename_all = "snake_case")]
121pub enum ActorKind {
122 User,
123 Agent,
124 Bridge,
125 Import,
126 System,
127}
128
129wire_enum!(ActorKind, "document actor kind", {
130 User => "user",
131 Agent => "agent",
132 Bridge => "bridge",
133 Import => "import",
134 System => "system",
135});
136
137#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
138#[serde(rename_all = "snake_case")]
139pub enum RevisionOriginKind {
140 McpExecution,
141 BridgeDevice,
142 WebSession,
143 EditSession,
144 Api,
145}
146
147wire_enum!(RevisionOriginKind, "revision origin kind", {
148 McpExecution => "mcp_execution",
149 BridgeDevice => "bridge_device",
150 WebSession => "web_session",
151 EditSession => "edit_session",
152 Api => "api",
153});
154
155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
156#[serde(rename_all = "snake_case")]
157pub enum ProposalStatus {
158 Open,
159 Accepted,
160 Rejected,
161 Superseded,
162}
163
164wire_enum!(ProposalStatus, "proposal status", {
165 Open => "open",
166 Accepted => "accepted",
167 Rejected => "rejected",
168 Superseded => "superseded",
169});
170
171#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
175#[serde(rename_all = "snake_case")]
176pub enum AgentEditPolicy {
177 #[default]
178 Direct,
179 Propose,
180}
181
182wire_enum!(AgentEditPolicy, "agent edit policy", {
183 Direct => "direct",
184 Propose => "propose",
185});
186
187#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
188#[serde(rename_all = "snake_case")]
189pub enum EditMode {
190 Land,
191 Propose,
192}
193
194wire_enum!(EditMode, "edit mode", {
195 Land => "land",
196 Propose => "propose",
197});
198
199#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
200#[serde(rename_all = "snake_case")]
201pub enum GrantEventKind {
202 Granted,
203 Changed,
204 Revoked,
205 RevokedAll,
206 Transferred,
207 Expired,
208}
209
210wire_enum!(GrantEventKind, "grant event", {
211 Granted => "granted",
212 Changed => "changed",
213 Revoked => "revoked",
214 RevokedAll => "revoked_all",
215 Transferred => "transferred",
216 Expired => "expired",
217});
218
219#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
220#[serde(rename_all = "snake_case")]
221pub enum AccessRequestStatus {
222 Open,
223 Granted,
224 Declined,
225}
226
227wire_enum!(AccessRequestStatus, "access request status", {
228 Open => "open",
229 Granted => "granted",
230 Declined => "declined",
231});