ralph/queue/operations/
fields.rs1use super::validate::{ensure_task_id, parse_rfc3339_utc, validate_custom_field_key};
17use crate::contracts::QueueFile;
18use anyhow::{Result, anyhow};
19
20#[derive(Debug, Clone)]
22pub struct TaskFieldPreview {
23 pub task_id: String,
24 pub key: String,
25 pub old_value: Option<String>,
26 pub new_value: String,
27}
28
29pub fn preview_set_field(
31 queue: &QueueFile,
32 task_id: &str,
33 key: &str,
34 value: &str,
35) -> Result<TaskFieldPreview> {
36 let operation = "preview field set";
37 let key_trimmed = key.trim();
38 let needle = ensure_task_id(task_id, operation)?;
39 validate_custom_field_key(key_trimmed, needle, operation)?;
40
41 let task = queue
42 .tasks
43 .iter()
44 .find(|t| t.id.trim() == needle)
45 .ok_or_else(|| {
46 anyhow!(
47 "{}",
48 crate::error_messages::task_not_found_for_edit(operation, needle)
49 )
50 })?;
51
52 let old_value = task.custom_fields.get(key_trimmed).cloned();
53 let new_value = value.trim().to_string();
54
55 Ok(TaskFieldPreview {
56 task_id: needle.to_string(),
57 key: key_trimmed.to_string(),
58 old_value,
59 new_value,
60 })
61}
62
63pub fn set_field(
64 queue: &mut QueueFile,
65 task_id: &str,
66 key: &str,
67 value: &str,
68 now_rfc3339: &str,
69) -> Result<()> {
70 let operation = "custom field set";
71 let key_trimmed = key.trim();
72 let needle = ensure_task_id(task_id, operation)?;
73 validate_custom_field_key(key_trimmed, needle, operation)?;
74
75 let now = parse_rfc3339_utc(now_rfc3339)?;
76
77 let task = queue
78 .tasks
79 .iter_mut()
80 .find(|t| t.id.trim() == needle)
81 .ok_or_else(|| {
82 anyhow!(
83 "{}",
84 crate::error_messages::task_not_found_for_edit(operation, needle)
85 )
86 })?;
87
88 task.custom_fields
89 .insert(key_trimmed.to_string(), value.trim().to_string());
90 task.updated_at = Some(now);
91
92 Ok(())
93}