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    pub fn system() -> Self {
39        Self {
40            owner_id: "system".to_string(),
41            owner_kind: OwnerKind::System,
42        }
43    }
44
45    pub fn from_actor(actor: &Actor) -> Self {
46        match actor {
47            Actor::User { user_id } => Self {
48                owner_id: user_id.clone(),
49                owner_kind: OwnerKind::User,
50            },
51            Actor::ServiceUser { service_name } => Self {
52                owner_id: service_name.clone(),
53                owner_kind: OwnerKind::Service,
54            },
55            Actor::System { operation } => Self {
56                owner_id: operation.clone(),
57                owner_kind: OwnerKind::System,
58            },
59            Actor::Anonymous => Self {
60                owner_id: "anonymous".to_string(),
61                owner_kind: OwnerKind::System,
62            },
63        }
64    }
65}
66
67/// Ownership behavior declared in schema DSL (`ownership: { ... }`).
68#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
69pub struct OwnershipConfig {
70    #[serde(default)]
71    pub system_owned: bool,
72    #[serde(default, skip_serializing_if = "Option::is_none")]
73    pub resolve: Option<String>,
74}
75
76#[cfg(test)]
77mod tests {
78    use super::{OwnerKind, OwnerRef};
79    use crate::Actor;
80
81    #[test]
82    fn owner_ref_from_user_actor() {
83        let r = OwnerRef::from_actor(&Actor::User {
84            user_id: "u42".into(),
85        });
86        assert_eq!(r.owner_id, "u42");
87        assert_eq!(r.owner_kind, OwnerKind::User);
88    }
89}