Skip to main content

polydat_core/kernel/subcontext/
name.rs

1// Copyright 2024-2026 Jonathan Shook
2// SPDX-License-Identifier: Apache-2.0
3
4//! [`ChildName`] — structured identifier for a spawned child.
5//!
6//! Per SRD-67 §"Named-child registry": each parent records the
7//! names it has spawned children under so duplicate spawn under
8//! the same name is caught at the API boundary. Names are
9//! `PathBuf`-shaped (hierarchical, comparable, debug-printable);
10//! the runtime constructs them from workload scope-tree node
11//! labels (phase / op-template / iteration coordinate).
12
13use std::fmt;
14
15/// Hierarchical identifier for a spawned sub-context.
16///
17/// Internally a slash-separated string of segments. Constructors
18/// match common workload-tree shapes:
19///
20/// - [`ChildName::phase`] — `phase/<name>`
21/// - [`ChildName::op`] — `op/<name>`
22/// - [`ChildName::iteration`] — `iter/<coord>`
23/// - [`ChildName::compose`] — append a segment under a parent name
24///
25/// Two names compare equal when their segment vectors are equal.
26#[derive(Debug, Clone, PartialEq, Eq, Hash)]
27pub struct ChildName {
28    segments: Vec<String>,
29}
30
31impl ChildName {
32    /// Create from raw segments. Used by tests / advanced callers
33    /// that have a pre-built path; production code prefers the
34    /// shape-specific constructors below.
35    pub fn from_segments<I, S>(segments: I) -> Self
36    where
37        I: IntoIterator<Item = S>,
38        S: Into<String>,
39    {
40        Self {
41            segments: segments.into_iter().map(Into::into).collect(),
42        }
43    }
44
45    /// `phase/<name>` — for a workload phase scope.
46    pub fn phase(name: impl Into<String>) -> Self {
47        Self {
48            segments: vec!["phase".into(), name.into()],
49        }
50    }
51
52    /// `op/<name>` — for an op-template scope under a phase.
53    pub fn op(name: impl Into<String>) -> Self {
54        Self {
55            segments: vec!["op".into(), name.into()],
56        }
57    }
58
59    /// `iter/<coord>` — for one iteration of a comprehension scope.
60    /// `coord` is the coordinate-tuple debug rendering used by the
61    /// scope-tree pre-walk.
62    pub fn iteration(coord: impl Into<String>) -> Self {
63        Self {
64            segments: vec!["iter".into(), coord.into()],
65        }
66    }
67
68    /// Compose: append `segment` to `parent_name`'s path.
69    pub fn compose(parent_name: &ChildName, segment: impl Into<String>) -> Self {
70        let mut segments = parent_name.segments.clone();
71        segments.push(segment.into());
72        Self { segments }
73    }
74
75    /// Borrow the segment list.
76    pub fn segments(&self) -> &[String] {
77        &self.segments
78    }
79
80    /// Render as a slash-joined path for diagnostics.
81    pub fn display(&self) -> String {
82        self.segments.join("/")
83    }
84}
85
86impl fmt::Display for ChildName {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        f.write_str(&self.display())
89    }
90}