uqa_storage/catalog/
sequence_security.rs1use serde::{Deserialize, Deserializer, Serialize, Serializer};
10pub use uqa_core::catalog_sequence::{BoundSequenceSecurity, LegacySequenceSecurity};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum SequenceSecurityRow {
14 Bound(BoundSequenceSecurity),
15 Legacy(LegacySequenceSecurity),
16}
17
18impl SequenceSecurityRow {
19 pub fn bootstrap() -> Self {
20 Self::Bound(BoundSequenceSecurity::owner(
21 uqa_core::catalog_role::RoleIdentity::BOOTSTRAP,
22 ))
23 }
24
25 pub fn legacy(role_owner: impl Into<String>) -> Self {
26 Self::Legacy(LegacySequenceSecurity::owner(role_owner))
27 }
28}
29
30impl From<BoundSequenceSecurity> for SequenceSecurityRow {
31 fn from(row: BoundSequenceSecurity) -> Self {
32 Self::Bound(row)
33 }
34}
35
36impl Serialize for SequenceSecurityRow {
37 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
38 #[derive(Serialize)]
39 struct Bound<'a> {
40 sequence_security_format: u32,
41 #[serde(flatten)]
42 security: &'a BoundSequenceSecurity,
43 }
44 match self {
45 Self::Bound(security) => Bound {
46 sequence_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 SequenceSecurityRow {
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("sequence_security_format") {
60 if version.as_u64() != Some(1) {
61 return Err(D::Error::custom("unsupported sequence security format"));
62 }
63 value
64 .as_object_mut()
65 .expect("version belongs to an object")
66 .remove("sequence_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;