use std::fmt;
use crate::workspace::WorkspaceId;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SymbolId(u64);
impl SymbolId {
#[must_use]
pub const fn new(raw: u64) -> Self {
Self(raw)
}
#[must_use]
pub const fn as_u64(self) -> u64 {
self.0
}
}
impl fmt::Display for SymbolId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "#{}", self.0)
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct ScopedSymbolId {
pub workspace: WorkspaceId,
pub local: SymbolId,
}
impl ScopedSymbolId {
#[must_use]
pub const fn new(workspace: WorkspaceId, local: SymbolId) -> Self {
Self { workspace, local }
}
}
impl fmt::Display for ScopedSymbolId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}@{}", self.local, self.workspace)
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum SymbolKind {
Agent,
Document,
Registry,
Service,
Policy,
Memory,
InferenceMethod,
Scope,
Predicate,
EventType,
Workspace,
Literal,
}
#[cfg(test)]
mod tests {
use super::*;
use ulid::Ulid;
#[test]
fn symbol_id_roundtrip() {
for raw in [0_u64, 1, 42, u64::MAX] {
assert_eq!(SymbolId::new(raw).as_u64(), raw);
}
}
#[test]
fn scoped_symbol_distinguishes_workspaces() {
let ws_a = WorkspaceId::from_ulid(Ulid::from_parts(1, 1));
let ws_b = WorkspaceId::from_ulid(Ulid::from_parts(2, 2));
let a = ScopedSymbolId::new(ws_a, SymbolId::new(42));
let b = ScopedSymbolId::new(ws_b, SymbolId::new(42));
assert_ne!(a, b);
}
#[test]
fn scoped_symbol_equal_when_workspace_and_local_match() {
let ws = WorkspaceId::from_ulid(Ulid::from_parts(7, 7));
let a = ScopedSymbolId::new(ws, SymbolId::new(99));
let b = ScopedSymbolId::new(ws, SymbolId::new(99));
assert_eq!(a, b);
}
#[test]
fn symbol_kind_is_nonexhaustive_pattern() {
let kind = SymbolKind::Agent;
let label = match kind {
SymbolKind::Agent => "agent",
SymbolKind::Document => "document",
SymbolKind::Registry => "registry",
SymbolKind::Service => "service",
SymbolKind::Policy => "policy",
SymbolKind::Memory => "memory",
SymbolKind::InferenceMethod => "inference_method",
SymbolKind::Scope => "scope",
SymbolKind::Predicate => "predicate",
SymbolKind::EventType => "event_type",
SymbolKind::Workspace => "workspace",
SymbolKind::Literal => "literal",
};
assert_eq!(label, "agent");
}
}