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//! 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). See
12//! subcontext_construction.md §4.1.
13
14use std::fmt;
15
16/// Hierarchical identifier for a spawned sub-context.
17///
18/// Internally a slash-separated string of segments. Constructors
19/// match common workload-tree shapes:
20///
21/// - [`ChildName::phase`] — `phase/<name>`
22/// - [`ChildName::op`] — `op/<name>`
23/// - [`ChildName::iteration`] — `iter/<coord>`
24/// - [`ChildName::compose`] — append a segment under a parent name
25///
26/// Two names compare equal when their segment vectors are equal.
27#[derive(Debug, Clone, PartialEq, Eq, Hash)]
28pub struct ChildName {
29    segments: Vec<String>,
30}
31
32impl ChildName {
33    /// Create from raw segments. Used by tests / advanced callers
34    /// that have a pre-built path; production code prefers the
35    /// shape-specific constructors below.
36    pub fn from_segments<I, S>(segments: I) -> Self
37    where
38        I: IntoIterator<Item = S>,
39        S: Into<String>,
40    {
41        Self {
42            segments: segments.into_iter().map(Into::into).collect(),
43        }
44    }
45
46    /// `phase/<name>` — for a workload phase scope.
47    pub fn phase(name: impl Into<String>) -> Self {
48        Self {
49            segments: vec!["phase".into(), name.into()],
50        }
51    }
52
53    /// `op/<name>` — for an op-template scope under a phase.
54    pub fn op(name: impl Into<String>) -> Self {
55        Self {
56            segments: vec!["op".into(), name.into()],
57        }
58    }
59
60    /// `iter/<coord>` — for one iteration of a comprehension scope.
61    /// `coord` is the coordinate-tuple debug rendering used by the
62    /// scope-tree pre-walk.
63    pub fn iteration(coord: impl Into<String>) -> Self {
64        Self {
65            segments: vec!["iter".into(), coord.into()],
66        }
67    }
68
69    /// Compose: append `segment` to `parent_name`'s path.
70    pub fn compose(parent_name: &ChildName, segment: impl Into<String>) -> Self {
71        let mut segments = parent_name.segments.clone();
72        segments.push(segment.into());
73        Self { segments }
74    }
75
76    /// Borrow the segment list.
77    pub fn segments(&self) -> &[String] {
78        &self.segments
79    }
80
81    /// Render as a slash-joined path for diagnostics.
82    pub fn display(&self) -> String {
83        self.segments.join("/")
84    }
85}
86
87impl fmt::Display for ChildName {
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        f.write_str(&self.display())
90    }
91}