Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions engine/proto/engine.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ service Engine {
rpc CreateTask(Task) returns (Task);
rpc DeleteTask(TaskSelector) returns (empty);
rpc GetTasks(TaskPageRequest) returns (TaskPage);
rpc CheckAuth(empty) returns (empty);
}
message TaskSelector {
TaskState state = 1;
Expand Down
213 changes: 163 additions & 50 deletions engine/src/bin/packer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,69 +110,182 @@ async fn main() {
buf.push(unw);
}
let ns = buf.join("\n");
let mut file = File::create("schema.rustforge.toml").unwrap();
file.write_all(ns.as_bytes()).unwrap();
match File::create("schema.rustforge.toml") {
Ok(mut file) => {
if let Err(e) = file.write_all(ns.as_bytes()) {
error!("Failed to write schema file: {}", e);
} else {
info!("Wrote schema.rustforge.toml");
}
}
Err(e) => {
error!("Failed to create schema file: {}", e);
}
}
}
Commands::Unpack(input) => {
if input.input.exists() {
let mut final_out: Vec<String> = Vec::new();
info!("Unpacking File: {}", input.input.to_string_lossy());
let mut buf = Vec::new();
File::open(input.input)
.unwrap()
.read_to_end(&mut buf)
.unwrap();
let k: TaskQueue = bincode::deserialize(&buf).unwrap();
for tasks in k.tasks {
let tt = api.task_registry.tasks.get(&tasks.0.clone()).unwrap();
for task in tasks.1 {
if tt.verify(task.bytes.clone()) {
let tmp_nt = tt.from_bytes(&task.bytes);
final_out.push(format![
r#"[["{}:{}"]]"#,
tasks.0.0.clone(),
tasks.0.1.clone()
]);
final_out.push(tmp_nt.to_toml());
info!("{:?}", tmp_nt);
};

// Attempt to open and read the input file. If either step fails,
// we do not proceed to deserialization or writing the output file.
match File::open(&input.input) {
Ok(mut f) => {
if let Err(e) = f.read_to_end(&mut buf) {
error!(
"Failed to read input file {}: {}",
input.input.display(),
e
);
// reading failed -> do not proceed to deserialize or write
return;
}
}
Err(e) => {
error!("Failed to open input file {}: {}", input.input.display(), e);
// opening failed -> do not proceed to deserialize or write
return;
}
}
let ns = final_out.join("\n");
let mut file = File::create("output.rustforge.toml").unwrap();
file.write_all(ns.as_bytes()).unwrap();

// Try to deserialize. Only on successful deserialization do we
// process entries and write the output TOML file.
let maybe_queue: Option<TaskQueue> =
match bincode::deserialize::<TaskQueue>(&buf) {
Ok(k) => Some(k),
Err(e) => {
error!("Failed to deserialize task queue: {}", e);
None
}
};

if let Some(k) = maybe_queue {
let mut final_out: Vec<String> = Vec::new();

for tasks in k.tasks {
match api.task_registry.tasks.get(&tasks.0.clone()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for all task_registry access patterns
rg -n 'task_registry\.(tasks\.)?get' --type rust -C 2

Repository: GrandEngineering/engine

Length of output: 1224


🏁 Script executed:

#!/bin/bash
# Read lines around 217-218 in packer.rs
sed -n '210,225p' engine/src/bin/packer.rs

# Search for TaskRegistry struct definition
rg -n 'struct TaskRegistry|impl.*TaskRegistry' --type rust -A 5

Repository: GrandEngineering/engine

Length of output: 1585


🏁 Script executed:

#!/bin/bash
# Find TaskRegistry struct definition
rg -n 'struct.*TaskRegistry|pub struct.*TaskRegistry' --type rust -A 10

# Find Registry trait definition
rg -n 'trait Registry' --type rust -A 10

Repository: GrandEngineering/engine

Length of output: 1086


🏁 Script executed:

#!/bin/bash
# Read full context around line 167 to understand usage
sed -n '165,175p' engine/src/bin/packer.rs

Repository: GrandEngineering/engine

Length of output: 727


🏁 Script executed:

#!/bin/bash
# Find the actual implementation of the get() method for EngineTaskRegistry
rg -n 'fn get' enginelib/src/api.rs -A 5 | head -20

Repository: GrandEngineering/engine

Length of output: 315


Use the consistent .get() method instead of direct field access.

Line 167 uses api.task_registry.tasks.get(...) (direct HashMap access) while the rest of the codebase uses api.task_registry.get(...) (the Registry trait method). Both work functionally but return different types—Arc<dyn Task> vs Box<dyn Task> respectively. For consistency with the Registry API pattern used elsewhere (e.g., lines 217-218, server.rs:528, server.rs:603), use .get() instead.

🤖 Prompt for AI Agents
In engine/src/bin/packer.rs around line 167, replace the direct HashMap access
api.task_registry.tasks.get(&tasks.0.clone()) with the Registry API call
api.task_registry.get(&tasks.0) to match the rest of the codebase; update any
downstream handling to accept the type returned by api.task_registry.get (adjust
variable ownership/borrowing or convert the returned Box/Arc as needed) so the
code uses the registry's .get() method consistently.

Some(tt) => {
for task in tasks.1 {
if tt.verify(task.bytes.clone()) {
let tmp_nt = tt.from_bytes(&task.bytes);
final_out.push(format![
r#"[["{}:{}"]]"#,
tasks.0.0.clone(),
tasks.0.1.clone()
]);
final_out.push(tmp_nt.to_toml());
info!("{:?}", tmp_nt);
}
}
}
None => {
error!("Unknown template for {}:{}", tasks.0.0, tasks.0.1);
}
}
}

let ns = final_out.join("\n");
match File::create("output.rustforge.toml") {
Ok(mut file) => {
if let Err(e) = file.write_all(ns.as_bytes()) {
error!("Failed to write output.rustforge.toml: {}", e);
} else {
info!("Wrote output.rustforge.toml");
}
}
Err(e) => {
error!("Failed to create output.rustforge.toml: {}", e);
}
}
} else {
// Deserialization failed; we logged the error above and intentionally do not
// create/write the output file to avoid producing an empty output.
}
}
}
Commands::Pack(input) => {
if input.input.exists() {
info!("Packing File: {}", input.input.to_string_lossy());
let toml_str = std::fs::read_to_string(input.input).unwrap();
let raw: RawDoc = toml::from_str(&toml_str).unwrap();
let entries = parse_entries(raw);
for entry in entries {
let template = api
.task_registry
.get(&ID(entry.namespace.as_str(), entry.id.as_str()))
.unwrap();
let toml_string = toml::to_string(&entry.data).unwrap();
let t = template.from_toml(toml_string);
let mut tmp = api
.task_queue
.tasks
.get(&ID(entry.namespace.as_str(), entry.id.as_str()))
.unwrap()
.clone();
tmp.push(StoredTask {
id: "".into(), //ids are minted on the server
bytes: t.to_bytes(),
});
api.task_queue
.tasks
.insert(ID(entry.namespace.as_str(), entry.id.as_str()), tmp);
match std::fs::read_to_string(&input.input) {
Ok(toml_str) => {
match toml::from_str::<RawDoc>(&toml_str) {
Ok(raw) => {
let entries = parse_entries(raw);
for entry in entries {
match api
.task_registry
.get(&ID(entry.namespace.as_str(), entry.id.as_str()))
{
Some(template) => {
match toml::to_string(&entry.data) {
Ok(toml_string) => {
let t = template.from_toml(toml_string);
let key = ID(
entry.namespace.as_str(),
entry.id.as_str(),
);
let mut vec = api
.task_queue
.tasks
.get(&key)
.cloned()
.unwrap_or_default();
vec.push(StoredTask {
id: "".into(), //ids are minted on the server
bytes: t.to_bytes(),
});
api.task_queue.tasks.insert(key, vec);
}
Err(e) => {
error!(
"Failed to convert entry data to TOML string: {}",
e
);
}
}
}
None => {
error!(
"Template not found for {}:{}",
entry.namespace, entry.id
);
}
}
}
match bincode::serialize(&api.task_queue) {
Ok(data) => match File::create("output.rustforge.bin") {
Ok(mut file) => {
if let Err(e) = file.write_all(&data) {
error!(
"Failed to write output.rustforge.bin: {}",
e
);
} else {
info!("Wrote output.rustforge.bin");
}
}
Err(e) => {
error!(
"Failed to create output.rustforge.bin: {}",
e
);
}
},
Err(e) => {
error!("Failed to serialize task queue: {}", e);
}
}
}
Err(e) => {
error!("Failed to parse input TOML: {}", e);
}
}
}
Err(e) => {
error!("Failed to read input file {}: {}", input.input.display(), e);
}
}
let data = bincode::serialize(&api.task_queue).unwrap();
let mut file = File::create("output.rustforge.bin").unwrap();
file.write_all(&data).unwrap();
} else {
error!("File does not exist: {}", input.input.to_string_lossy())
}
Expand Down
Loading
Loading