use serde::Serialize; #[derive(Debug, Serialize)] pub struct RobotMeta { pub elapsed_ms: u64, } /// Filter JSON object fields in-place for `--fields` support. /// Retains only the specified field names on each item in the list array. pub fn filter_fields(value: &mut serde_json::Value, list_key: &str, fields: &[String]) { if fields.is_empty() { return; } if let Some(items) = value .get_mut("data") .and_then(|d| d.get_mut(list_key)) .and_then(|v| v.as_array_mut()) { for item in items { if let Some(obj) = item.as_object_mut() { obj.retain(|k, _| fields.iter().any(|f| f == k)); } } } } /// Expand the `minimal` preset into concrete field names. pub fn expand_fields_preset(fields: &[String], entity: &str) -> Vec { if fields.len() == 1 && fields[0] == "minimal" { match entity { "issues" => ["iid", "title", "state", "updated_at_iso"] .iter() .map(|s| (*s).to_string()) .collect(), "mrs" => ["iid", "title", "state", "updated_at_iso"] .iter() .map(|s| (*s).to_string()) .collect(), "search" => ["document_id", "title", "source_type", "score"] .iter() .map(|s| (*s).to_string()) .collect(), "timeline" => ["timestamp", "type", "entity_iid", "detail"] .iter() .map(|s| (*s).to_string()) .collect(), "who_expert" => ["username", "score"] .iter() .map(|s| (*s).to_string()) .collect(), "who_workload" => ["iid", "title", "state"] .iter() .map(|s| (*s).to_string()) .collect(), "who_active" => ["entity_type", "iid", "title", "participants"] .iter() .map(|s| (*s).to_string()) .collect(), "who_overlap" => ["username", "touch_count"] .iter() .map(|s| (*s).to_string()) .collect(), "who_reviews" => ["name", "count", "percentage"] .iter() .map(|s| (*s).to_string()) .collect(), "notes" => ["id", "author_username", "body", "created_at_iso"] .iter() .map(|s| (*s).to_string()) .collect(), "me_items" => ["iid", "title", "attention_state", "updated_at_iso"] .iter() .map(|s| (*s).to_string()) .collect(), "me_activity" => ["timestamp_iso", "event_type", "entity_iid", "actor"] .iter() .map(|s| (*s).to_string()) .collect(), _ => fields.to_vec(), } } else { fields.to_vec() } } /// Strip `response_schema` from every command entry for `--brief` mode. pub fn strip_schemas(commands: &mut serde_json::Value) { if let Some(map) = commands.as_object_mut() { for (_cmd_name, cmd) in map.iter_mut() { if let Some(obj) = cmd.as_object_mut() { obj.remove("response_schema"); obj.remove("example_output"); } } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_expand_fields_preset_notes() { let fields = vec!["minimal".to_string()]; let expanded = expand_fields_preset(&fields, "notes"); assert_eq!( expanded, ["id", "author_username", "body", "created_at_iso"] ); } #[test] fn test_expand_fields_preset_passthrough() { let fields = vec!["id".to_string(), "body".to_string()]; let expanded = expand_fields_preset(&fields, "notes"); assert_eq!(expanded, ["id", "body"]); } }