inkling/error/runtime/
variable.rs1use std::{error::Error, fmt};
4
5use crate::line::Variable;
6
7use std::cmp::Ordering;
8
9impl Error for VariableError {}
10
11#[derive(Clone, Debug)]
12pub struct VariableError {
14 pub variable: Variable,
16 pub kind: VariableErrorKind,
18}
19
20impl VariableError {
21 pub(crate) fn from_kind<T: Into<Variable>>(variable: T, kind: VariableErrorKind) -> Self {
22 VariableError {
23 variable: variable.into(),
24 kind,
25 }
26 }
27}
28
29#[derive(Clone, Debug)]
30pub enum VariableErrorKind {
32 DividedByZero {
34 other: Variable,
36 operator: char,
38 },
39 InvalidComparison {
41 other: Variable,
43 comparison: Ordering,
45 },
46 InvalidOperation {
48 other: Variable,
50 operator: char,
52 },
53 NonMatchingAssignment {
55 other: Variable,
57 },
58}
59
60impl fmt::Display for VariableError {
61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62 use VariableErrorKind::*;
63
64 let variable = &self.variable;
65
66 match &self.kind {
67 DividedByZero { other, operator } => write!(
68 f,
69 "Attempted to divide by 0 in the operation '{} {} {}'",
70 variable.to_string_simple(),
71 operator,
72 other.to_string_simple()
73 ),
74 InvalidComparison { other, comparison } => {
75 let operator = match comparison {
76 Ordering::Equal => "==",
77 Ordering::Less => ">",
78 Ordering::Greater => "<",
79 };
80
81 write!(
82 f,
83 "Cannot compare variable of type '{}' to '{}' using the '{op}' operator \
84 (in: '{} {op} {}')",
85 variable.variant_string(),
86 other.variant_string(),
87 variable.to_string_simple(),
88 other.to_string_simple(),
89 op = operator
90 )
91 }
92 InvalidOperation { other, operator } => write!(
93 f,
94 "Operation '{op}' is not allowed between variables of type '{}' and '{}' \
95 (in: '{} {op} {}')",
96 variable.variant_string(),
97 other.variant_string(),
98 variable.to_string_simple(),
99 other.to_string_simple(),
100 op = operator
101 ),
102 NonMatchingAssignment { other } => write!(
103 f,
104 "Cannot assign a value of type '{}' to a variable of type '{}' \
105 (variables cannot change type)",
106 other.variant_string(),
107 variable.variant_string()
108 ),
109 }
110 }
111}