sift_queue/cli/
formatters.rs1use crate::queue::Item;
2
3pub fn print_item_summary(item: &Item) {
6 let mut type_counts: Vec<(String, usize)> = Vec::new();
8 for source in &item.sources {
9 if let Some(entry) = type_counts.iter_mut().find(|(t, _)| *t == source.type_) {
10 entry.1 += 1;
11 } else {
12 type_counts.push((source.type_.clone(), 1));
13 }
14 }
15 let source_types: String = type_counts
16 .iter()
17 .map(|(t, c)| {
18 if *c > 1 {
19 format!("{}:{}", t, c)
20 } else {
21 t.clone()
22 }
23 })
24 .collect::<Vec<_>>()
25 .join(",");
26
27 let label = match (&item.title, &item.description) {
28 (Some(t), _) => t.clone(),
29 (None, Some(d)) => d.clone(),
30 (None, None) => String::new(),
31 };
32
33 let priority = item
34 .priority
35 .map(|value| format!(" [priority:{}]", value))
36 .unwrap_or_default();
37
38 println!(
39 "{} [{}]{} {} {} {}",
40 item.id, item.status, priority, label, source_types, item.created_at
41 );
42}
43
44pub fn print_item_detail(item: &Item) {
46 println!("Item: {}", item.id);
47 if let Some(ref title) = item.title {
48 println!("Title: {}", title);
49 }
50 if let Some(ref description) = item.description {
51 println!("Description: {}", description);
52 }
53 println!("Status: {}", item.status);
54 if let Some(priority) = item.priority {
55 println!("Priority: {}", priority);
56 }
57 println!("Created: {}", item.created_at);
58 println!("Updated: {}", item.updated_at);
59
60 if !item.blocked_by.is_empty() {
61 println!("Blocked by: {}", item.blocked_by.join(", "));
62 }
63
64 if let serde_json::Value::Object(ref map) = item.metadata {
65 if !map.is_empty() {
66 println!("Metadata:");
67 for (k, v) in map {
68 println!(" {}: {}", k, v);
69 }
70 }
71 }
72
73 println!("Sources: ({})", item.sources.len());
74 for (i, source) in item.sources.iter().enumerate() {
75 print_source(source, i);
76 }
77}
78
79fn print_source(source: &crate::queue::Source, index: usize) {
81 let location = if let Some(ref path) = source.path {
82 path.clone()
83 } else if source.content.is_some() {
84 "[inline]".to_string()
85 } else {
86 "[empty]".to_string()
87 };
88
89 println!(" [{}] {}: {}", index, source.type_, location);
90
91 if let (Some(ref content), None) = (&source.content, &source.path) {
92 let lines: Vec<&str> = content.lines().collect();
93 let preview: Vec<&str> = lines.iter().take(3).copied().collect();
94 let preview_str = preview.join("\n ");
95 println!(" {}", preview_str);
96 if lines.len() > 3 {
97 println!(" ...");
98 }
99 }
100}