mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-18 02:07:43 +00:00
134 lines
4.1 KiB
Dart
134 lines
4.1 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:decimal/decimal.dart';
|
|
|
|
final _ten = BigInt.from(10);
|
|
|
|
class Amount {
|
|
Amount({
|
|
required BigInt rawValue,
|
|
required this.fractionDigits,
|
|
}) : assert(fractionDigits >= 0),
|
|
_value = rawValue;
|
|
|
|
/// special zero case with [fractionDigits] set to 0
|
|
static Amount get zero => Amount(
|
|
rawValue: BigInt.zero,
|
|
fractionDigits: 0,
|
|
);
|
|
|
|
/// truncate double value to [fractionDigits] places
|
|
Amount.fromDouble(double amount, {required this.fractionDigits})
|
|
: assert(fractionDigits >= 0),
|
|
_value =
|
|
Decimal.parse(amount.toString()).shift(fractionDigits).toBigInt();
|
|
|
|
/// truncate decimal value to [fractionDigits] places
|
|
Amount.fromDecimal(Decimal amount, {required this.fractionDigits})
|
|
: assert(fractionDigits >= 0),
|
|
_value = amount.shift(fractionDigits).toBigInt();
|
|
|
|
// ===========================================================================
|
|
// ======= Instance properties ===============================================
|
|
|
|
final int fractionDigits;
|
|
final BigInt _value;
|
|
|
|
// ===========================================================================
|
|
// ======= Getters ===========================================================
|
|
|
|
/// raw base value
|
|
BigInt get raw => _value;
|
|
|
|
/// actual decimal vale represented
|
|
Decimal get decimal =>
|
|
(Decimal.fromBigInt(_value) / _ten.pow(fractionDigits).toDecimal())
|
|
.toDecimal(scaleOnInfinitePrecision: fractionDigits);
|
|
|
|
/// convenience getter
|
|
@Deprecated("provided for convenience only. Use fractionDigits instead.")
|
|
int get decimals => fractionDigits;
|
|
|
|
// ===========================================================================
|
|
// ======= Serialization =====================================================
|
|
|
|
Map<String, dynamic> toMap() {
|
|
return {"raw": raw.toString(), "fractionDigits": fractionDigits};
|
|
}
|
|
|
|
String toJsonString() {
|
|
return jsonEncode(toMap());
|
|
}
|
|
|
|
// ===========================================================================
|
|
// ======= Deserialization ===================================================
|
|
|
|
static Amount fromSerializedJsonString(String json) {
|
|
final map = jsonDecode(json) as Map;
|
|
return Amount(
|
|
rawValue: BigInt.parse(map["raw"] as String),
|
|
fractionDigits: map["fractionDigits"] as int,
|
|
);
|
|
}
|
|
|
|
// ===========================================================================
|
|
// ======= operators =========================================================
|
|
|
|
bool operator >(Amount other) => raw > other.raw;
|
|
|
|
bool operator <(Amount other) => raw < other.raw;
|
|
|
|
bool operator >=(Amount other) => raw >= other.raw;
|
|
|
|
bool operator <=(Amount other) => raw <= other.raw;
|
|
|
|
Amount operator +(Amount other) {
|
|
if (fractionDigits != other.fractionDigits) {
|
|
throw ArgumentError(
|
|
"fractionDigits do not match: this=$this, other=$other");
|
|
}
|
|
return Amount(
|
|
rawValue: raw + other.raw,
|
|
fractionDigits: fractionDigits,
|
|
);
|
|
}
|
|
|
|
Amount operator -(Amount other) {
|
|
if (fractionDigits != other.fractionDigits) {
|
|
throw ArgumentError(
|
|
"fractionDigits do not match: this=$this, other=$other");
|
|
}
|
|
return Amount(
|
|
rawValue: raw - other.raw,
|
|
fractionDigits: fractionDigits,
|
|
);
|
|
}
|
|
|
|
Amount operator *(Amount other) {
|
|
if (fractionDigits != other.fractionDigits) {
|
|
throw ArgumentError(
|
|
"fractionDigits do not match: this=$this, other=$other");
|
|
}
|
|
return Amount(
|
|
rawValue: raw * other.raw,
|
|
fractionDigits: fractionDigits,
|
|
);
|
|
}
|
|
|
|
// ===========================================================================
|
|
// ======= Overrides =========================================================
|
|
|
|
@override
|
|
String toString() => "Amount($raw, $fractionDigits)";
|
|
|
|
@override
|
|
bool operator ==(Object other) =>
|
|
identical(this, other) ||
|
|
other is Amount &&
|
|
runtimeType == other.runtimeType &&
|
|
raw == other.raw &&
|
|
fractionDigits == other.fractionDigits;
|
|
|
|
@override
|
|
int get hashCode => Object.hashAll([raw, fractionDigits]);
|
|
}
|