///|
pub(all) enum DiagnosticSeverity {
Error
Warning
} derive(Eq, Debug)
///|
pub struct Diagnostic {
severity_value : DiagnosticSeverity
code_value : String
message_value : String
line_value : Int
} derive(Eq, Debug)
///|
pub fn Diagnostic::severity(self : Diagnostic) -> DiagnosticSeverity {
self.severity_value
}
///|
pub fn Diagnostic::code(self : Diagnostic) -> String {
self.code_value
}
///|
pub fn Diagnostic::message(self : Diagnostic) -> String {
self.message_value
}
///|
pub fn Diagnostic::line(self : Diagnostic) -> Int {
self.line_value
}
///|
pub struct SafetyPolicy {
max_x_value : Double
max_y_value : Double
max_z_value : Double
reject_negative_feed : Bool
} derive(Eq, Debug)
///|
pub fn SafetyPolicy::standard() -> SafetyPolicy {
{
max_x_value: 1000.0,
max_y_value: 1000.0,
max_z_value: 500.0,
reject_negative_feed: true,
}
}
///|
pub fn SafetyPolicy::with_workspace(
self : SafetyPolicy,
x : Double,
y : Double,
z : Double,
) -> SafetyPolicy {
{ ..self, max_x_value: x, max_y_value: y, max_z_value: z }
}
///|
/// Check workspace bounds and unsafe feed values without connecting to a machine.
pub fn diagnose(
program : GCodeProgram,
policy? : SafetyPolicy = SafetyPolicy::standard(),
) -> Array[Diagnostic] {
let issues : Array[Diagnostic] = []
for motion in program.motions() {
let end = motion.end()
if end.x() < 0.0 || end.x() > policy.max_x_value {
issues.push({
severity_value: Error,
code_value: "axis.x_out_of_bounds",
message_value: "X position exceeds workspace",
line_value: motion.source_line(),
})
}
if end.y() < 0.0 || end.y() > policy.max_y_value {
issues.push({
severity_value: Error,
code_value: "axis.y_out_of_bounds",
message_value: "Y position exceeds workspace",
line_value: motion.source_line(),
})
}
if end.z() < 0.0 || end.z() > policy.max_z_value {
issues.push({
severity_value: Error,
code_value: "axis.z_out_of_bounds",
message_value: "Z position exceeds workspace",
line_value: motion.source_line(),
})
}
match motion.feed() {
Some(feed) =>
if policy.reject_negative_feed && feed < 0.0 {
issues.push({
severity_value: Error,
code_value: "feed.negative",
message_value: "feed rate cannot be negative",
line_value: motion.source_line(),
})
}
None => ()
}
}
issues
}
///|
pub fn render_diagnostics(diagnostics : Array[Diagnostic]) -> String {
let mut output = "diagnostics=" + diagnostics.length().to_string() + "\n"
for issue in diagnostics {
let severity = match issue.severity() {
Error => "error"
Warning => "warning"
}
output = output +
severity +
" " +
issue.code() +
" line=" +
issue.line().to_string() +
": " +
issue.message() +
"\n"
}
output
}