Skip to main content

valence_core/
owner_ref.rs

1//! Stable owner identity for row-level ownership metadata.
2
3use serde::{Deserialize, Serialize};
4
5use crate::Actor;
6
7/// Kind of principal that owns a row.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(rename_all = "snake_case")]
10pub enum OwnerKind {
11    User,
12    Account,
13    Application,
14    System,
15    Service,
16}
17
18impl OwnerKind {
19    pub fn as_str(self) -> &'static str {
20        match self {
21            OwnerKind::User => "user",
22            OwnerKind::Account => "account",
23            OwnerKind::Application => "application",
24            OwnerKind::System => "system",
25            OwnerKind::Service => "service",
26        }
27    }
28}
29
30/// Resolved owner for a row (stored in ownership tables at the host layer).
31#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
32pub struct OwnerRef {
33    pub owner_id: String,
34    pub owner_kind: OwnerKind,
35}
36
37impl OwnerRef {
38    #[must_use]
39    pub fn system() -> Self {
40        Self {
41            owner_id: "system".to_string(),
42            owner_kind: OwnerKind::System,
43        }
44    }
45
46    #[must_use]
47    pub fn from_actor(actor: &Actor) -> Self {
48        match actor {
49            Actor::User { user_id } => Self {
50                owner_id: user_id.clone(),
51                owner_kind: OwnerKind::User,
52            },
53            Actor::ServiceUser { service_name } => Self {
54                owner_id: service_name.clone(),
55                owner_kind: OwnerKind::Service,
56            },
57            Actor::System { operation } => Self {
58                owner_id: operation.clone(),
59                owner_kind: OwnerKind::System,
60            },
61            Actor::Anonymous => Self {
62                owner_id: "anonymous".to_string(),
63                owner_kind: OwnerKind::System,
64            },
65        }
66    }
67}
68
69/// Ownership behavior declared in schema DSL (`ownership: { ... }`).
70#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
71pub struct OwnershipConfig {
72    #[serde(default)]
73    pub system_owned: bool,
74    #[serde(default, skip_serializing_if = "Option::is_none")]
75    pub resolve: Option<String>,
76}
77
78#[cfg(test)]
79mod tests {
80    use super::{OwnerKind, OwnerRef};
81    use crate::Actor;
82
83    #[test]
84    fn owner_ref_from_user_actor() {
85        let r = OwnerRef::from_actor(&Actor::User {
86            user_id: "u42".into(),
87        });
88        assert_eq!(r.owner_id, "u42");
89        assert_eq!(r.owner_kind, OwnerKind::User);
90    }
91}