Files
whetstone_DSL/editor/src/TaskCompletionMetrics.h

87 lines
2.6 KiB
C++

#pragma once
// Step 685: Task completion outcome metrics.
#include <algorithm>
#include <string>
#include <vector>
struct TaskOutcome {
std::string taskId;
int linesChanged = 0;
int linesAdded = 0;
int linesRemoved = 0;
bool testsProvided = false;
bool testsPassed = false;
int qualityRating = 0;
std::string notes;
};
class TaskCompletionMetrics {
public:
static TaskOutcome diff(const std::string& taskId,
const std::string& before,
const std::string& after,
bool testsPassed,
int qualityRating,
const std::string& notes = "") {
TaskOutcome out;
out.taskId = taskId;
out.testsPassed = testsPassed;
out.testsProvided = testsPassed;
out.qualityRating = std::clamp(qualityRating, 0, 100);
out.notes = notes;
const auto beforeLines = splitLines(before);
const auto afterLines = splitLines(after);
size_t prefix = 0;
while (prefix < beforeLines.size() &&
prefix < afterLines.size() &&
beforeLines[prefix] == afterLines[prefix]) {
++prefix;
}
size_t suffix = 0;
while (suffix + prefix < beforeLines.size() &&
suffix + prefix < afterLines.size() &&
beforeLines[beforeLines.size() - 1 - suffix] ==
afterLines[afterLines.size() - 1 - suffix]) {
++suffix;
}
const int removed = static_cast<int>(beforeLines.size() - prefix - suffix);
const int added = static_cast<int>(afterLines.size() - prefix - suffix);
out.linesRemoved = std::max(0, removed);
out.linesAdded = std::max(0, added);
out.linesChanged = out.linesAdded + out.linesRemoved;
return out;
}
static int countLines(const std::string& text) {
if (text.empty()) return 0;
int lines = 1;
for (char c : text) if (c == '\n') ++lines;
if (!text.empty() && text.back() == '\n') --lines;
return lines;
}
private:
static std::vector<std::string> splitLines(const std::string& text) {
std::vector<std::string> out;
std::string current;
for (char c : text) {
if (c == '\n') {
out.push_back(current);
current.clear();
} else {
current.push_back(c);
}
}
if (!text.empty() && text.back() != '\n') {
out.push_back(current);
}
return out;
}
};