laminar_core/catalog/
mod.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum CatalogObjectKind {
9 Source,
11 Sink,
13 Table,
15 LookupTable,
17 Stream,
19 MaterializedView,
21}
22
23impl std::fmt::Display for CatalogObjectKind {
24 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 formatter.write_str(match self {
26 Self::Source => "source",
27 Self::Sink => "sink",
28 Self::Table => "table",
29 Self::LookupTable => "lookup table",
30 Self::Stream => "stream",
31 Self::MaterializedView => "materialized view",
32 })
33 }
34}
35
36pub const STAGE_MARKER: &str = "$stage";
38
39#[must_use]
42pub fn stage_owner(name: &str) -> Option<&str> {
43 let (owner, index) = name.rsplit_once(STAGE_MARKER)?;
44 (!owner.is_empty() && !index.is_empty() && index.bytes().all(|byte| byte.is_ascii_digit()))
45 .then_some(owner)
46}
47
48#[cfg(test)]
49mod tests {
50 use super::stage_owner;
51
52 #[test]
53 fn stage_names_round_trip_to_their_owner() {
54 assert_eq!(stage_owner("out$stage1"), Some("out"));
55 assert_eq!(stage_owner("a$stage2$stage12"), Some("a$stage2"));
56 for name in ["out", "$stage1", "out$stage", "out$stagex", "out$stage1a"] {
57 assert_eq!(stage_owner(name), None, "{name}");
58 }
59 }
60}