feat(core): add cell value types and error kinds
This commit is contained in:
1 parent
d72fd68b28
commit
7e2d745898
1 file changed
+134
@@ -0,0 +1,134 @@
|
|||||||
|
enum ErrorKind {
|
||||||
|
divZero('#DIV/0!'),
|
||||||
|
ref('#REF!'),
|
||||||
|
cycle('#CYCLE!'),
|
||||||
|
name('#NAME?'),
|
||||||
|
value('#VALUE!'),
|
||||||
|
numError('#NUM!'),
|
||||||
|
parse('#ERROR!'),
|
||||||
|
na('#N/A');
|
||||||
|
|
||||||
|
final String symbol;
|
||||||
|
const ErrorKind(this.symbol);
|
||||||
|
|
||||||
|
static ErrorKind? fromSymbol(String symbol) {
|
||||||
|
for (final kind in ErrorKind.values) {
|
||||||
|
if (kind.symbol == symbol) return kind;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed class CellValue {
|
||||||
|
const CellValue();
|
||||||
|
|
||||||
|
String display();
|
||||||
|
}
|
||||||
|
|
||||||
|
class NumberValue extends CellValue {
|
||||||
|
final double value;
|
||||||
|
const NumberValue(this.value);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String display() => formatNumber(value);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => other is NumberValue && other.value == value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => value.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'NumberValue(${display()})';
|
||||||
|
}
|
||||||
|
|
||||||
|
class TextValue extends CellValue {
|
||||||
|
final String value;
|
||||||
|
const TextValue(this.value);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String display() => value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => other is TextValue && other.value == value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => value.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'TextValue($value)';
|
||||||
|
}
|
||||||
|
|
||||||
|
class BooleanValue extends CellValue {
|
||||||
|
final bool value;
|
||||||
|
const BooleanValue(this.value);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String display() => value ? 'TRUE' : 'FALSE';
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => other is BooleanValue && other.value == value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => value.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'BooleanValue($value)';
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlankValue extends CellValue {
|
||||||
|
const BlankValue();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String display() => '';
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => other is BlankValue;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'BlankValue()';
|
||||||
|
}
|
||||||
|
|
||||||
|
class ErrorValue extends CellValue {
|
||||||
|
final ErrorKind kind;
|
||||||
|
const ErrorValue(this.kind);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String display() => kind.symbol;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) => other is ErrorValue && other.kind == kind;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => kind.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'ErrorValue(${kind.symbol})';
|
||||||
|
}
|
||||||
|
|
||||||
|
class EvalException implements Exception {
|
||||||
|
final ErrorValue error;
|
||||||
|
const EvalException(this.error);
|
||||||
|
|
||||||
|
ErrorKind get kind => error.kind;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'EvalException(${error.kind.symbol})';
|
||||||
|
}
|
||||||
|
|
||||||
|
String formatNumber(double value) {
|
||||||
|
if (value.isNaN) return ErrorKind.numError.symbol;
|
||||||
|
if (value.isInfinite) return value.isNegative ? '-Infinity' : 'Infinity';
|
||||||
|
if (value == value.roundToDouble() && value.abs() < 1e15) {
|
||||||
|
return value.toInt().toString();
|
||||||
|
}
|
||||||
|
var text = value.toStringAsPrecision(12);
|
||||||
|
if (text.contains('.') && !text.contains('e') && !text.contains('E')) {
|
||||||
|
text = text.replaceFirst(RegExp(r'0+$'), '');
|
||||||
|
text = text.replaceFirst(RegExp(r'\.$'), '');
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user