Skip to main content

ruvix_shell/commands/
tasks.rs

1//! Task listing command implementation.
2
3use crate::{ShellBackend, TaskState};
4use alloc::format;
5use alloc::string::String;
6
7/// Convert task state to display string.
8fn state_str(state: TaskState) -> &'static str {
9    match state {
10        TaskState::Ready => "READY",
11        TaskState::Running => "RUN",
12        TaskState::Blocked => "BLOCK",
13        TaskState::Sleeping => "SLEEP",
14        TaskState::Exited => "EXIT",
15    }
16}
17
18/// Extract task name from fixed-size buffer.
19fn task_name(name: &[u8; 16]) -> String {
20    let end = name.iter().position(|&b| b == 0).unwrap_or(16);
21    String::from_utf8_lossy(&name[..end]).into_owned()
22}
23
24/// Execute the tasks command.
25#[must_use]
26pub fn execute<B: ShellBackend>(backend: &B) -> String {
27    let tasks = backend.task_list();
28
29    if tasks.is_empty() {
30        return String::from("No tasks.");
31    }
32
33    let mut output = String::from("Task List\n=========\n");
34    output.push_str("  ID   NAME             STATE   PRI  PART  CPU   CAPS\n");
35    output.push_str("  ---  ---------------  ------  ---  ----  ----  ----\n");
36
37    for task in &tasks {
38        let name = task_name(&task.name);
39        let line = format!(
40            "  {:<3}  {:<15}  {:<6}  {:>3}  {:>4}  0x{:02X}  {:>4}\n",
41            task.id,
42            if name.len() > 15 {
43                &name[..15]
44            } else {
45                &name
46            },
47            state_str(task.state),
48            task.priority,
49            task.partition,
50            task.cpu_affinity,
51            task.cap_count
52        );
53        output.push_str(&line);
54    }
55
56    output.push_str(&format!("\nTotal: {} task(s)", tasks.len()));
57    output
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn test_state_str() {
66        assert_eq!(state_str(TaskState::Ready), "READY");
67        assert_eq!(state_str(TaskState::Running), "RUN");
68        assert_eq!(state_str(TaskState::Blocked), "BLOCK");
69        assert_eq!(state_str(TaskState::Sleeping), "SLEEP");
70        assert_eq!(state_str(TaskState::Exited), "EXIT");
71    }
72
73    #[test]
74    fn test_task_name() {
75        let name1 = *b"test\0\0\0\0\0\0\0\0\0\0\0\0";
76        assert_eq!(task_name(&name1), "test");
77
78        let name2 = *b"very_long_name!!";
79        assert_eq!(task_name(&name2), "very_long_name!!");
80
81        let name3 = [0u8; 16];
82        assert_eq!(task_name(&name3), "");
83    }
84}