Skip to main content

morphir_core/traversal/
event.rs

1//! Format-neutral events for traversing versioned Morphir IR.
2
3use crate::ir::{classic, v4};
4use crate::naming::PackageName;
5
6use super::IrCursor;
7
8/// A concrete Classic v3 module released as one streaming unit.
9pub type ClassicV3Module = classic::ModuleEntry<classic::Attrs, classic::Type<classic::Attrs>>;
10
11/// Distribution metadata emitted before dependencies and modules.
12#[derive(Debug, Clone, PartialEq)]
13pub enum DistributionHeader {
14    /// A Classic v3 library distribution.
15    ClassicV3Library { package: classic::Path },
16    /// A Classic v3 specification distribution, introduced in format version 3.1.0.
17    ClassicV3Specs { package: classic::Path },
18    /// A v4 library distribution.
19    V4Library {
20        format_version: v4::FormatVersion,
21        package: PackageName,
22    },
23    /// A v4 specification distribution.
24    V4Specs {
25        format_version: v4::FormatVersion,
26        package: PackageName,
27    },
28    /// A v4 application distribution.
29    V4Application {
30        format_version: v4::FormatVersion,
31        package: PackageName,
32        entry_points: v4::EntryPoints,
33    },
34}
35
36/// One dependency specification in a versioned distribution.
37#[derive(Debug, Clone, PartialEq)]
38pub enum DependencyEvent {
39    /// A dependency represented with Classic v3 concrete types.
40    ClassicV3 {
41        package: classic::Path,
42        specification: classic::PackageSpecification<classic::Attrs>,
43    },
44    /// A dependency represented with v4 concrete types.
45    V4 {
46        package: String,
47        specification: v4::PackageSpecification,
48    },
49    /// A dependency an application links statically, carried as a package definition
50    /// (distributions-0010).
51    V4Definition {
52        package: String,
53        definition: v4::PackageDefinition,
54    },
55}
56
57/// One module in a versioned distribution.
58#[derive(Debug, Clone, PartialEq)]
59pub enum ModuleEvent {
60    /// A Classic v3 module definition.
61    ClassicV3(ClassicV3Module),
62    /// A Classic v3 module specification, the module kind of a v3 Specs distribution.
63    ClassicV3Specification {
64        path: classic::Path,
65        specification: classic::ModuleSpecification<classic::Attrs>,
66    },
67    /// A v4 module definition and its access control.
68    V4Definition {
69        path: String,
70        module: v4::AccessControlled<v4::ModuleDefinition>,
71    },
72    /// A v4 module specification.
73    V4Specification {
74        path: String,
75        module: v4::ModuleSpecification,
76    },
77}
78
79/// The semantic payload of one format-neutral traversal event.
80#[derive(Debug, Clone, PartialEq)]
81pub enum SemanticEventKind {
82    /// Starts a distribution.
83    Begin(DistributionHeader),
84    /// Document-owned 4.1.0 metadata, emitted immediately after the header.
85    DocumentMetadata(Box<v4::DocumentMeta>),
86    /// Provides one dependency specification.
87    Dependency(DependencyEvent),
88    /// Provides one module.
89    Module(ModuleEvent),
90    /// Ends the distribution.
91    End,
92}
93
94/// A semantic IR event paired with its version-independent location.
95#[derive(Debug, Clone, PartialEq)]
96pub struct SemanticEvent {
97    cursor: IrCursor,
98    kind: SemanticEventKind,
99}
100
101impl SemanticEvent {
102    /// Create a semantic event at the supplied cursor.
103    pub fn new(cursor: IrCursor, kind: SemanticEventKind) -> Self {
104        Self { cursor, kind }
105    }
106
107    /// Return the semantic location of this event.
108    pub fn cursor(&self) -> &IrCursor {
109        &self.cursor
110    }
111
112    /// Return the event payload.
113    pub fn kind(&self) -> &SemanticEventKind {
114        &self.kind
115    }
116
117    /// Consume this value and return its cursor and payload.
118    pub fn into_parts(self) -> (IrCursor, SemanticEventKind) {
119        (self.cursor, self.kind)
120    }
121}