ralph/queue/loader/
read.rs1use super::maintenance::maintain_and_save_loaded_queues;
17use super::validation::validate_loaded_queues;
18use crate::config::Resolved;
19use crate::contracts::QueueFile;
20use crate::queue::json_repair::attempt_json_repair;
21use crate::queue::validation::{self, ValidationWarning};
22use anyhow::{Context, Result};
23use std::path::Path;
24
25pub fn load_queue_or_default(path: &Path) -> Result<QueueFile> {
27 if !path.exists() {
28 return Ok(QueueFile::default());
29 }
30 load_queue(path)
31}
32
33pub fn load_queue(path: &Path) -> Result<QueueFile> {
35 let raw = std::fs::read_to_string(path)
36 .with_context(|| format!("read queue file {}", path.display()))?;
37 let queue = crate::jsonc::parse_jsonc::<QueueFile>(&raw, &format!("queue {}", path.display()))?;
38 Ok(queue)
39}
40
41pub fn load_queue_with_repair(path: &Path) -> Result<QueueFile> {
44 let raw = std::fs::read_to_string(path)
45 .with_context(|| format!("read queue file {}", path.display()))?;
46
47 match crate::jsonc::parse_jsonc::<QueueFile>(&raw, &format!("queue {}", path.display())) {
48 Ok(queue) => Ok(queue),
49 Err(parse_err) => {
50 log::warn!("Queue JSON parse error, attempting repair: {}", parse_err);
51
52 if let Some(repaired) = attempt_json_repair(&raw) {
53 match crate::jsonc::parse_jsonc::<QueueFile>(
54 &repaired,
55 &format!("repaired queue {}", path.display()),
56 ) {
57 Ok(queue) => {
58 log::info!("Successfully repaired queue JSON");
59 Ok(queue)
60 }
61 Err(repair_err) => Err(parse_err).with_context(|| {
62 format!(
63 "parse queue {} as JSON/JSONC (repair also failed: {})",
64 path.display(),
65 repair_err
66 )
67 })?,
68 }
69 } else {
70 Err(parse_err)
71 }
72 }
73 }
74}
75
76pub fn load_queue_with_repair_and_validate(
83 path: &Path,
84 done: Option<&crate::contracts::QueueFile>,
85 id_prefix: &str,
86 id_width: usize,
87 max_dependency_depth: u8,
88) -> Result<(QueueFile, Vec<ValidationWarning>)> {
89 let queue = load_queue_with_repair(path)?;
90
91 let warnings = if let Some(d) = done {
92 validation::validate_queue_set(&queue, Some(d), id_prefix, id_width, max_dependency_depth)
93 .with_context(|| format!("validate repaired queue {}", path.display()))?
94 } else {
95 validation::validate_queue(&queue, id_prefix, id_width)
96 .with_context(|| format!("validate repaired queue {}", path.display()))?;
97 Vec::new()
98 };
99
100 Ok((queue, warnings))
101}
102
103fn load_queue_set_with_repair(
104 resolved: &Resolved,
105 include_done: bool,
106) -> Result<(QueueFile, QueueFile, bool)> {
107 let queue_file = load_queue_with_repair(&resolved.queue_path)?;
108 let done_path_exists = resolved.done_path.exists();
109 let done_file = if done_path_exists {
110 load_queue_with_repair(&resolved.done_path)?
111 } else {
112 QueueFile::default()
113 };
114
115 let done_file = if include_done || done_path_exists {
116 done_file
117 } else {
118 QueueFile::default()
119 };
120
121 Ok((queue_file, done_file, done_path_exists))
122}
123
124pub fn load_and_validate_queues(
129 resolved: &Resolved,
130 include_done: bool,
131) -> Result<(QueueFile, Option<QueueFile>)> {
132 let (queue_file, done_for_validation, _done_path_exists) =
133 load_queue_set_with_repair(resolved, include_done)?;
134 validate_loaded_queues(resolved, &queue_file, &done_for_validation)?;
135
136 let done_file = if include_done {
137 Some(done_for_validation)
138 } else {
139 None
140 };
141
142 Ok((queue_file, done_file))
143}
144
145pub fn repair_and_validate_queues(
150 resolved: &Resolved,
151 include_done: bool,
152) -> Result<(QueueFile, Option<QueueFile>)> {
153 let (mut queue_file, mut done_for_validation, done_path_exists) =
154 load_queue_set_with_repair(resolved, true)?;
155
156 maintain_and_save_loaded_queues(
157 &resolved.queue_path,
158 &mut queue_file,
159 &resolved.done_path,
160 done_path_exists,
161 &mut done_for_validation,
162 )?;
163
164 validate_loaded_queues(resolved, &queue_file, &done_for_validation)?;
165
166 let done_file = if include_done {
167 Some(done_for_validation)
168 } else {
169 None
170 };
171
172 Ok((queue_file, done_file))
173}