pepl_codegen/
source_map.rs1use serde::{Deserialize, Serialize};
11
12#[derive(Debug, Clone, Default, Serialize, Deserialize)]
14pub struct SourceMap {
15 pub entries: Vec<SourceMapEntry>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct SourceMapEntry {
21 pub wasm_func_index: u32,
23 pub func_name: String,
26 pub kind: FuncKind,
28 pub span: pepl_types::Span,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
34#[serde(rename_all = "snake_case")]
35pub enum FuncKind {
36 SpaceInfra,
38 Action,
40 View,
42 Update,
44 HandleEvent,
46 Test,
48 TestCount,
50 Lambda,
52 InvokeLambda,
54}
55
56impl SourceMap {
57 pub fn new() -> Self {
58 Self {
59 entries: Vec::new(),
60 }
61 }
62
63 pub fn push(
65 &mut self,
66 wasm_func_index: u32,
67 func_name: impl Into<String>,
68 kind: FuncKind,
69 span: pepl_types::Span,
70 ) {
71 self.entries.push(SourceMapEntry {
72 wasm_func_index,
73 func_name: func_name.into(),
74 kind,
75 span,
76 });
77 }
78
79 pub fn find_by_func_index(&self, idx: u32) -> Option<&SourceMapEntry> {
81 self.entries.iter().find(|e| e.wasm_func_index == idx)
82 }
83
84 pub fn to_json(&self) -> Vec<u8> {
86 serde_json::to_vec(self).unwrap_or_default()
87 }
88
89 pub fn from_json(data: &[u8]) -> Option<Self> {
91 serde_json::from_slice(data).ok()
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98 use pepl_types::Span;
99
100 #[test]
101 fn round_trip_json() {
102 let mut sm = SourceMap::new();
103 sm.push(35, "init", FuncKind::SpaceInfra, Span::new(5, 3, 10, 4));
104 sm.push(36, "dispatch_action", FuncKind::SpaceInfra, Span::new(12, 3, 30, 4));
105 sm.push(37, "increment", FuncKind::Action, Span::new(15, 5, 18, 6));
106
107 let json = sm.to_json();
108 let sm2 = SourceMap::from_json(&json).expect("parse failed");
109 assert_eq!(sm2.entries.len(), 3);
110 assert_eq!(sm2.entries[0].func_name, "init");
111 assert_eq!(sm2.entries[2].kind, FuncKind::Action);
112 }
113
114 #[test]
115 fn find_by_func_index() {
116 let mut sm = SourceMap::new();
117 sm.push(35, "init", FuncKind::SpaceInfra, Span::new(5, 3, 10, 4));
118 sm.push(36, "dispatch", FuncKind::SpaceInfra, Span::new(12, 3, 30, 4));
119
120 assert!(sm.find_by_func_index(35).is_some());
121 assert_eq!(sm.find_by_func_index(35).unwrap().func_name, "init");
122 assert!(sm.find_by_func_index(99).is_none());
123 }
124}