Skip to content

Commit 2753dbd

Browse files
committed
Conditions #26
- Refactor conditions and evaluators to use visitor pattern.
1 parent 0ef0ac4 commit 2753dbd

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

lib/src/api/models/condition.dart

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ enum ConditionOperation {
6666
return '<';
6767
}
6868
}
69+
70+
/// Allows the provided [visitor] to visit this operation.
71+
bool accept(Object? left, Object? right, ConditionOperatorVisitor visitor) {
72+
switch (this) {
73+
case ConditionOperation.equalsTo:
74+
return visitor.visitEqualsOperator(left, right);
75+
case ConditionOperation.notEqualsTo:
76+
return visitor.visitNotEqualsOperator(left, right);
77+
case ConditionOperation.greaterThan:
78+
return visitor.visitGreaterThanOperator(left, right);
79+
case ConditionOperation.lessThan:
80+
return visitor.visitLessThanOperator(left, right);
81+
}
82+
}
6983
}
7084

7185
/// join operator for complex conditions
@@ -113,6 +127,9 @@ sealed class BaseExpression with EquatableMixin, SerializableMixin {
113127
throw UnimplementedError('Unregistered type: ${json['type']}');
114128
}
115129
}
130+
131+
/// Allows the provided [visitor] to visit this expression.
132+
R? accept<R>(ExpressionVisitor<R> visitor);
116133
}
117134

118135
/// Represents an expression part in an expression. e.g. `a == b` has two
@@ -132,6 +149,9 @@ sealed class ExpressionPart with EquatableMixin, SerializableMixin {
132149
throw UnimplementedError('Unregistered type: ${json['type']}');
133150
}
134151
}
152+
153+
/// Allows the provided [visitor] to visit this expression part.
154+
R? accept<R>(ExpressionPartVisitor<R> visitor);
135155
}
136156

137157
/// Represents a raw value in an expression. e.g. `a == 1` has a raw value of
@@ -153,13 +173,18 @@ class RawValuePart extends ExpressionPart {
153173

154174
@override
155175
Map toJson() => _$RawValuePartToJson(this)..['type'] = 'RawValue';
176+
177+
@override
178+
R? accept<R>(ExpressionPartVisitor<R> visitor) =>
179+
visitor.visitRawValuePart(this);
156180
}
157181

158182
/// Represents a variable in an expression. e.g. `a == b` has two variables:
159183
/// `a` and `b`.
160184
@JsonSerializable()
161185
class VariablePart extends ExpressionPart {
162186
@JsonKey(defaultValue: '')
187+
163188
/// the actual string interpolated with variables.
164189
final String valueString;
165190

@@ -199,6 +224,10 @@ class VariablePart extends ExpressionPart {
199224

200225
@override
201226
Map toJson() => _$VariablePartToJson(this)..['type'] = 'Variable';
227+
228+
@override
229+
R? accept<R>(ExpressionPartVisitor<R> visitor) =>
230+
visitor.visitVariablePart(this);
202231
}
203232

204233
/// Represents a simple expression in a condition. e.g. `a == b` is an
@@ -245,6 +274,9 @@ class Expression extends BaseExpression {
245274

246275
@override
247276
Map toJson() => _$ExpressionToJson(this)..['type'] = 'Expression';
277+
278+
@override
279+
R? accept<R>(ExpressionVisitor<R> visitor) => visitor.visitExpression(this);
248280
}
249281

250282
/// Represents a group of expressions in a condition typically joined by
@@ -292,6 +324,10 @@ class ExpressionGroup extends BaseExpression {
292324

293325
@override
294326
Map toJson() => _$ExpressionGroupToJson(this)..['type'] = 'ExpressionGroup';
327+
328+
@override
329+
R? accept<R>(ExpressionVisitor<R> visitor) =>
330+
visitor.visitExpressionGroup(this);
295331
}
296332

297333
/// Base class for conditions
@@ -316,6 +352,9 @@ sealed class BaseCondition with EquatableMixin, SerializableMixin {
316352
throw UnimplementedError('Unregistered type: ${json['type']}');
317353
}
318354
}
355+
356+
/// Allows the provided [visitor] to visit this condition.
357+
R? accept<R>(ConditionVisitor<R> visitor);
319358
}
320359

321360
/// Represents an else condition. e.g. `else { ... }`. [actions] are performed
@@ -355,6 +394,9 @@ class ElseCondition extends BaseCondition {
355394

356395
@override
357396
Map toJson() => _$ElseConditionToJson(this)..['type'] = 'ElseCondition';
397+
398+
@override
399+
R? accept<R>(ConditionVisitor<R> visitor) => visitor.visitElseCondition(this);
358400
}
359401

360402
/// Represents a condition.
@@ -404,6 +446,9 @@ class Condition extends BaseCondition {
404446

405447
@override
406448
Map toJson() => _$ConditionToJson(this)..['type'] = 'Condition';
449+
450+
@override
451+
R? accept<R>(ConditionVisitor<R> visitor) => visitor.visitCondition(this);
407452
}
408453

409454
/// Represents a group of conditions. Contains an if condition, else if
@@ -460,6 +505,10 @@ class ConditionGroup extends BaseCondition {
460505

461506
@override
462507
Map toJson() => _$ConditionGroupToJson(this)..['type'] = 'ConditionGroup';
508+
509+
@override
510+
R? accept<R>(ConditionVisitor<R> visitor) =>
511+
visitor.visitConditionGroup(this);
463512
}
464513

465514
/// Contains all the variables associated with a canvas inside a page.
@@ -526,3 +575,48 @@ class CanvasConditions with EquatableMixin {
526575
conditions[conditionId] = value;
527576
}
528577
}
578+
579+
/// A visitor that can be used to visit a [ConditionOperation].
580+
abstract interface class ConditionOperatorVisitor {
581+
/// Visits a [ConditionOperation].
582+
bool visitEqualsOperator(Object? left, Object? right);
583+
584+
/// Visits a [ConditionOperation].
585+
bool visitNotEqualsOperator(Object? left, Object? right);
586+
587+
/// Visits a [ConditionOperation].
588+
bool visitGreaterThanOperator(Object? left, Object? right);
589+
590+
/// Visits a [ConditionOperation].
591+
bool visitLessThanOperator(Object? left, Object? right);
592+
}
593+
594+
/// An interface for evaluating conditions.
595+
abstract interface class ConditionVisitor<R> {
596+
/// Evaluates the condition and returns the result.
597+
R? visitCondition(Condition condition);
598+
599+
/// Evaluates the condition group and returns the result.
600+
R? visitConditionGroup(ConditionGroup condition);
601+
602+
/// Evaluates the else condition and returns the result.
603+
R? visitElseCondition(ElseCondition condition);
604+
}
605+
606+
/// An interface for evaluating expressions.
607+
abstract interface class ExpressionVisitor<R> {
608+
/// Evaluates the expression and returns the result.
609+
R? visitExpression(Expression expression);
610+
611+
/// Evaluates the expression group and returns the result.
612+
R? visitExpressionGroup(ExpressionGroup expression);
613+
}
614+
615+
/// An interface for evaluating expression parts.
616+
abstract interface class ExpressionPartVisitor<R> {
617+
/// Evaluates the expression part and returns the result.
618+
R? visitRawValuePart(RawValuePart part);
619+
620+
/// Evaluates the expression part group and returns the result.
621+
R? visitVariablePart(VariablePart part);
622+
}

0 commit comments

Comments
 (0)