Skip to main content

polydat_core/kernel/
manifest.rs

1// Copyright 2024-2026 Jonathan Shook
2// SPDX-License-Identifier: Apache-2.0
3
4//! Output manifest — the typed contract a compiled Polydat program
5//! exposes to consumers.
6//!
7//! A `ManifestEntry` records `(name, port_type, modifier)` for one
8//! output of a [`crate::kernel::PolydatProgram`]. Synthesizers that
9//! emit Polydat source for descendant scopes consume manifests to
10//! decide which names a child can extern from a parent (auto-
11//! extern + `materialize_wiring_from_outer`) and what type to declare each
12//! extern as.
13//!
14//! Lives in the kernel module because the data it carries is
15//! pure Polydat metadata — name, port type, binding modifier — all
16//! of which already have homes in `kernel` / `ast` / `dsl`.
17
18use crate::ast::PortType;
19use crate::dsl::ast::BindingModifier;
20use crate::kernel::PolydatProgram;
21
22/// One entry in a program's output manifest: typed, modifier-
23/// aware view of a single output name.
24#[derive(Debug, Clone)]
25pub struct ManifestEntry {
26    /// The output's name.
27    pub name: String,
28    /// Its type.
29    pub port_type: PortType,
30    /// Its wire-coloring keywords.
31    pub modifier: BindingModifier,
32}
33
34/// Extract the output manifest from a compiled Polydat program.
35/// Returns one entry per output, in declaration order.
36pub fn extract_manifest(program: &PolydatProgram) -> Vec<ManifestEntry> {
37    (0..program.output_count())
38        .map(|i| {
39            let name = program.output_name(i).to_string();
40            let (ni, pi) = program.resolve_output_by_index(i);
41            let port_type = program.node_meta(ni).outs[pi].typ;
42            let modifier = program.output_modifier(&name);
43            ManifestEntry {
44                name,
45                port_type,
46                modifier,
47            }
48        })
49        .collect()
50}