uqa_storage/catalog/
relation_security.rs1use serde::{Deserialize, Deserializer, Serialize, Serializer};
10pub use uqa_core::catalog_acl::{BoundRelationSecurity, LegacyRelationSecurity};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum RelationSecurityRow {
14 Bound(BoundRelationSecurity),
15 Legacy(LegacyRelationSecurity),
16}
17
18impl RelationSecurityRow {
19 pub fn bootstrap() -> Self {
20 Self::Bound(BoundRelationSecurity::owner(
21 uqa_core::catalog_role::RoleIdentity::BOOTSTRAP,
22 ))
23 }
24
25 pub fn legacy(role_owner: impl Into<String>) -> Self {
26 Self::Legacy(LegacyRelationSecurity::owner(role_owner))
27 }
28}
29
30impl From<BoundRelationSecurity> for RelationSecurityRow {
31 fn from(row: BoundRelationSecurity) -> Self {
32 Self::Bound(row)
33 }
34}
35
36impl Serialize for RelationSecurityRow {
37 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
38 #[derive(Serialize)]
39 struct Bound<'a> {
40 relation_security_format: u32,
41 #[serde(flatten)]
42 security: &'a BoundRelationSecurity,
43 }
44 match self {
45 Self::Bound(security) => Bound {
46 relation_security_format: 1,
47 security,
48 }
49 .serialize(serializer),
50 Self::Legacy(security) => security.serialize(serializer),
51 }
52 }
53}
54
55impl<'de> Deserialize<'de> for RelationSecurityRow {
56 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
57 use serde::de::Error;
58 let mut value = serde_json::Value::deserialize(deserializer)?;
59 if let Some(version) = value.get("relation_security_format") {
60 if version.as_u64() != Some(1) {
61 return Err(D::Error::custom("unsupported relation security format"));
62 }
63 value
64 .as_object_mut()
65 .expect("version belongs to an object")
66 .remove("relation_security_format");
67 serde_json::from_value(value)
68 .map(Self::Bound)
69 .map_err(D::Error::custom)
70 } else {
71 serde_json::from_value(value)
72 .map(Self::Legacy)
73 .map_err(D::Error::custom)
74 }
75 }
76}
77
78#[cfg(test)]
79mod tests;