1use alloc::string::String;
4use alloc::vec::Vec;
5use core::time::Duration;
6use core::fmt::Write;
7
8#[cfg(feature = "serde")]
9use serde::Serialize;
10
11use crate::process::ErrorSummary;
12
13#[cfg_attr(feature = "serde", derive(Serialize))]
15pub struct Status {
16 pub running: bool,
17 pub output: String,
18 pub errors: Vec<ErrorSummary>,
19}
20
21pub const EMPTY_PROJECT: &str = include_str!("assets/empty-proj.xml");
25
26pub enum SyscallMenu {
32 Entry { label: String, value: String },
34 Submenu { label: String, content: Vec<SyscallMenu> },
36}
37impl SyscallMenu {
38 pub fn simple_entry(value: String) -> Self {
40 SyscallMenu::Entry { label: value.clone(), value }
41 }
42 fn format(items: &[Self]) -> String {
43 fn format_impl(value: &SyscallMenu, res: &mut String) {
44 match value {
45 SyscallMenu::Entry { label, value } => write!(res, "{label:?}:{value:?},").unwrap(),
46 SyscallMenu::Submenu { label, content } => {
47 write!(res, "{label:?}:{{").unwrap();
48 for value in content {
49 format_impl(value, res);
50 }
51 res.push_str("},");
52 }
53 }
54 }
55 let mut res = String::with_capacity(64);
56 res.push('{');
57 for item in items {
58 format_impl(item, &mut res);
59 }
60 res.push('}');
61 res
62 }
63}
64#[test]
65fn test_syscall_menu_format() {
66 assert_eq!(SyscallMenu::format(&[]), "{}");
67 assert_eq!(SyscallMenu::format(&[SyscallMenu::Entry { label: "foo".into(), value: "gtr".into() }]), r#"{"foo":"gtr",}"#);
68 assert_eq!(SyscallMenu::format(&[SyscallMenu::Entry { label: "foo".into(), value: "gtr".into() }, SyscallMenu::Entry { label: "bar".into(), value: "baz".into() }]), r#"{"foo":"gtr","bar":"baz",}"#);
69 assert_eq!(SyscallMenu::format(&[SyscallMenu::simple_entry("foo".into()), SyscallMenu::Submenu { label: "test".into(), content: vec![] }, SyscallMenu::Entry { label: "bam".into(), value: "s".into() }]), r#"{"foo":"foo","test":{},"bam":"s",}"#);
70 assert_eq!(SyscallMenu::format(&[SyscallMenu::Submenu { label: "tes\' \' \"t\"f".into(), content: vec![] }]), r#"{"tes' ' \"t\"f":{},}"#);
71 assert_eq!(SyscallMenu::format(&[SyscallMenu::Entry { label: "foo\"b\'ar".into(), value: "gtr\'\"test".into() }]), r#"{"foo\"b'ar":"gtr'\"test",}"#);
72
73}
74
75pub struct ExtensionArgs<'a> {
77 pub server: &'a str,
79 pub syscalls: &'a [SyscallMenu],
81 pub omitted_elements: &'a [&'a str],
83 pub pull_interval: Duration,
85}
86impl ExtensionArgs<'_> {
87 pub fn render(&self) -> String {
89 format!(include_str!("assets/extension.js"),
90 server = self.server,
91 syscalls = SyscallMenu::format(self.syscalls),
92 omitted_elements = self.omitted_elements,
93 pull_interval_ms = self.pull_interval.as_millis(),
94 )
95 }
96}