Jonatas Borges

update to 4.0

## [4.0.0-nullsafety.2]
## [4.0.0]
- Added append function to StateMixin. Now is possible track loading, success and error handle of your application with ONE LINE OF CODE. Ex: append(()=> api.getUser);
## [4.0.0-nullsafety.0]
- Migrate to null-safety
- Added ScrollMixin to controllers
- Added loadingMore status to RxStatus
... ...
... ... @@ -28,7 +28,7 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
get:
path: ../
get_test: ^3.13.3
#get_test: ^3.13.3
dependency_overrides:
get:
... ...
... ... @@ -87,7 +87,7 @@ void main() {
});
test('ever', () async {
RxString count = ''.obs;
final count = ''.obs;
var result = '';
ever<String>(count, (value) {
result = value;
... ...
... ... @@ -1011,7 +1011,7 @@ you can only use widgets and widget functions here''';
return key;
}
GlobalKey<NavigatorState>? nestedKey(int key) {
GlobalKey<NavigatorState>? nestedKey(dynamic key) {
keys.putIfAbsent(key, () => GlobalKey<NavigatorState>());
return keys[key];
}
... ... @@ -1158,7 +1158,7 @@ Since version 2.8 it is possible to access the properties
GlobalKey<NavigatorState>? get key => getxController.key;
Map<int, GlobalKey<NavigatorState>> get keys => getxController.keys;
Map<dynamic, GlobalKey<NavigatorState>> get keys => getxController.keys;
GetMaterialController get rootController => getxController;
... ...
... ... @@ -310,3 +310,64 @@ class GetMaterialApp extends StatelessWidget {
// actions: actions,
));
}
class GetNavigator extends StatelessWidget {
final List<GetPage> getPages;
const GetNavigator(
{Key? key,
required this.getPages,
this.pages = const <Page<dynamic>>[],
this.onPopPage,
this.initialRoute,
this.onGenerateInitialRoutes = Navigator.defaultGenerateInitialRoutes,
this.onGenerateRoute,
this.onUnknownRoute,
this.transitionDelegate = const DefaultTransitionDelegate<dynamic>(),
this.reportsRouteUpdateToEngine = false,
this.observers = const <NavigatorObserver>[],
this.restorationScopeId,
this.unKnownRoute})
: super(key: key);
final List<Page<dynamic>> pages;
final GetPage? unKnownRoute;
final PopPageCallback? onPopPage;
final TransitionDelegate<dynamic> transitionDelegate;
final String? initialRoute;
final RouteFactory? onGenerateRoute;
final RouteFactory? onUnknownRoute;
final List<NavigatorObserver> observers;
final String? restorationScopeId;
static const String defaultRouteName = '/';
final RouteListFactory onGenerateInitialRoutes;
final bool reportsRouteUpdateToEngine;
@override
Widget build(Object context) {
return Navigator(
pages: getPages,
onPopPage: onPopPage,
initialRoute: initialRoute,
onGenerateInitialRoutes: onGenerateInitialRoutes,
onGenerateRoute: onGenerateRoute,
onUnknownRoute: onUnknownRoute,
transitionDelegate: transitionDelegate,
reportsRouteUpdateToEngine: reportsRouteUpdateToEngine,
observers: observers,
restorationScopeId: restorationScopeId,
key: Get.nestedKey(key),
);
}
}
... ...
import 'package:flutter/widgets.dart';
import '../../../get_core/src/get_main.dart';
import '../../../get_instance/get_instance.dart';
import '../../get_navigation.dart';
import 'custom_transition.dart';
... ... @@ -11,7 +12,8 @@ class PathDecoded {
final List<String?> keys;
}
class GetPage {
class GetPage<T> extends Page<T> {
@override
final String name;
final GetPageBuilder page;
final bool? popGesture;
... ... @@ -31,6 +33,7 @@ class GetPage {
final List<GetPage>? children;
final List<GetMiddleware>? middlewares;
final PathDecoded path;
final GetPage? unknownRoute;
GetPage({
required this.name,
... ... @@ -51,6 +54,7 @@ class GetPage {
this.fullscreenDialog = false,
this.children,
this.middlewares,
this.unknownRoute,
}) : path = _nameToRegex(name);
static PathDecoded _nameToRegex(String path) {
... ... @@ -74,7 +78,7 @@ class GetPage {
return PathDecoded(RegExp('^$stringPath\$'), keys);
}
GetPage copyWith({
GetPage copy({
String? name,
GetPageBuilder? page,
bool? popGesture,
... ... @@ -115,4 +119,14 @@ class GetPage {
middlewares: middlewares ?? this.middlewares,
);
}
@override
Object? get arguments => Get.arguments;
@override
Route<T> createRoute(BuildContext context) {
return PageRedirect(
RouteSettings(name: name, arguments: Get.arguments), unknownRoute)
.page<T>();
}
}
... ...
... ... @@ -165,10 +165,10 @@ class PageRedirect {
{this.isUnknown = false, this.route});
// redirect all pages that needes redirecting
GetPageRoute page() {
GetPageRoute<T> page<T>() {
while (needRecheck()) {}
return isUnknown
? GetPageRoute(
? GetPageRoute<T>(
page: unknownRoute!.page,
parameter: unknownRoute!.parameter,
settings: RouteSettings(
... ... @@ -185,7 +185,7 @@ class PageRedirect {
fullscreenDialog: unknownRoute!.fullscreenDialog,
middlewares: unknownRoute!.middlewares,
)
: GetPageRoute(
: GetPageRoute<T>(
page: route!.page,
parameter: route!.parameter,
settings: RouteSettings(
... ...
... ... @@ -236,6 +236,8 @@ abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> {
}
}
extension RxBoolExt on Rx<bool> {}
/// Rx class for `bool` Type.
class RxBool extends _RxImpl<bool> {
RxBool(bool initial) : super(initial);
... ... @@ -266,143 +268,12 @@ class RxBool extends _RxImpl<bool> {
}
}
/// Rx class for `String` Type.
class RxString extends _RxImpl<String> implements Comparable<String>, Pattern {
RxString(String initial) : super(initial);
String operator +(String val) => _value + val;
/// Compares this string to [other].
@override
int compareTo(String other) {
return value.compareTo(other);
}
/// Returns true if this string ends with [other]. For example:
///
/// 'Dart'.endsWith('t'); // true
bool endsWith(String other) {
return value.endsWith(other);
}
/// Returns true if this string starts with a match of [pattern].
bool startsWith(Pattern pattern, [int index = 0]) {
return value.startsWith(pattern, index);
}
/// Returns the position of the first match of [pattern] in this string
int indexOf(Pattern pattern, [int start = 0]) {
return value.indexOf(pattern, start);
}
/// Returns the starting position of the last match [pattern] in this string,
/// searching backward starting at [start], inclusive:
int lastIndexOf(Pattern pattern, [int? start]) {
return value.lastIndexOf(pattern, start);
}
/// Returns true if this string is empty.
bool get isEmpty => value.isEmpty;
/// Returns true if this string is not empty.
bool get isNotEmpty => !isEmpty;
/// Returns the substring of this string that extends from [startIndex],
/// inclusive, to [endIndex], exclusive
String substring(int startIndex, [int? endIndex]) {
return value.substring(startIndex, endIndex);
}
/// Returns the string without any leading and trailing whitespace.
String trim() {
return value.trim();
}
/// Returns the string without any leading whitespace.
///
/// As [trim], but only removes leading whitespace.
String trimLeft() {
return value.trimLeft();
}
/// Returns the string without any trailing whitespace.
///
/// As [trim], but only removes trailing whitespace.
String trimRight() {
return value.trimRight();
}
/// Pads this string on the left if it is shorter than [width].
///
/// Return a new string that prepends [padding] onto this string
/// one time for each position the length is less than [width].
String padLeft(int width, [String padding = ' ']) {
return value.padLeft(width, padding);
}
/// Pads this string on the right if it is shorter than [width].
/// Return a new string that appends [padding] after this string
/// one time for each position the length is less than [width].
String padRight(int width, [String padding = ' ']) {
return value.padRight(width, padding);
}
/// Returns true if this string contains a match of [other]:
bool contains(Pattern other, [int startIndex = 0]) {
return value.contains(other, startIndex);
}
/// Replaces all substrings that match [from] with [replace].
String replaceAll(Pattern from, String replace) {
return value.replaceAll(from, replace);
}
/// Splits the string at matches of [pattern] and returns a list
/// of substrings.
List<String> split(Pattern pattern) {
return value.split(pattern);
}
/// Returns an unmodifiable list of the UTF-16 code units of this string.
List<int> get codeUnits => value.codeUnits;
/// Returns an [Iterable] of Unicode code-points of this string.
///
/// If the string contains surrogate pairs, they are combined and returned
/// as one integer by this iterator. Unmatched surrogate halves are treated
/// like valid 16-bit code-units.
Runes get runes => value.runes;
/// Converts all characters in this string to lower case.
/// If the string is already in all lower case, this method returns `this`.
String toLowerCase() {
return value.toLowerCase();
}
/// Converts all characters in this string to upper case.
/// If the string is already in all upper case, this method returns `this`.
String toUpperCase() {
return value.toUpperCase();
}
@override
Iterable<Match> allMatches(String string, [int start = 0]) {
return value.allMatches(string, start);
}
@override
Match? matchAsPrefix(String string, [int start = 0]) {
return value.matchAsPrefix(string, start);
}
}
/// Foundation class used for custom `Types` outside the common native Dart
/// types.
/// For example, any custom "Model" class, like User().obs will use `Rx` as
/// wrapper.
class Rx<T> extends _RxImpl<T?> {
Rx([T? initial]) : super(initial);
class Rx<T> extends _RxImpl<T> {
Rx(T initial) : super(initial);
@override
dynamic toJson() {
... ...
part of rx_types;
/// Base Rx class for all num Rx's.
abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
_BaseRxNum(T initial) : super(initial);
/// Addition operator. */
extension RxNumExt<T extends num> on Rx<T> {
/// Multiplication operator.
num operator *(num other) => value! * other;
num operator *(num other) => value * other;
/// Euclidean modulo operator.
///
... ... @@ -22,10 +17,10 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// The sign of the returned value `r` is always positive.
///
/// See [remainder] for the remainder of the truncating division.
num operator %(num other) => value! % other;
num operator %(num other) => value % other;
/// Division operator.
double operator /(num other) => value! / other;
double operator /(num other) => value / other;
/// Truncating division operator.
///
... ... @@ -34,10 +29,10 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
///
/// If both operands are [int]s then `a ~/ b` performs the truncating
/// integer division.
int operator ~/(num other) => value! ~/ other;
int operator ~/(num other) => value ~/ other;
/// Negate operator.
num operator -() => -value!;
num operator -() => -value;
/// Returns the remainder of the truncating division of `this` by [other].
///
... ... @@ -45,40 +40,40 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// `this == (this ~/ other) * other + r`.
/// As a consequence the remainder `r` has the same sign as the divider
/// `this`.
num remainder(num other) => value!.remainder(other);
num remainder(num other) => value.remainder(other);
/// Relational less than operator.
bool operator <(num other) => value! < other;
bool operator <(num other) => value < other;
/// Relational less than or equal operator.
bool operator <=(num other) => value! <= other;
bool operator <=(num other) => value <= other;
/// Relational greater than operator.
bool operator >(num other) => value! > other;
bool operator >(num other) => value > other;
/// Relational greater than or equal operator.
bool operator >=(num other) => value! >= other;
bool operator >=(num other) => value >= other;
/// True if the number is the double Not-a-Number value; otherwise, false.
bool get isNaN => value!.isNaN;
bool get isNaN => value.isNaN;
/// True if the number is negative; otherwise, false.
///
/// Negative numbers are those less than zero, and the double `-0.0`.
bool get isNegative => value!.isNegative;
bool get isNegative => value.isNegative;
/// True if the number is positive infinity or negative infinity; otherwise,
/// false.
bool get isInfinite => value!.isInfinite;
bool get isInfinite => value.isInfinite;
/// True if the number is finite; otherwise, false.
///
/// The only non-finite numbers are NaN, positive infinity, and
/// negative infinity.
bool get isFinite => value!.isFinite;
bool get isFinite => value.isFinite;
/// Returns the absolute value of this [num].
num abs() => value!.abs();
num abs() => value.abs();
/// Returns minus one, zero or plus one depending on the sign and
/// numerical value of the number.
... ... @@ -96,7 +91,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// n == n.sign * n.abs()
///
/// for all numbers `n` (except NaN, because NaN isn't `==` to itself).
num get sign => value!.sign;
num get sign => value.sign;
/// Returns the integer closest to `this`.
///
... ... @@ -104,23 +99,23 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// `(3.5).round() == 4` and `(-3.5).round() == -4`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int round() => value!.round();
int round() => value.round();
/// Returns the greatest integer no greater than `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int floor() => value!.floor();
int floor() => value.floor();
/// Returns the least integer no smaller than `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int ceil() => value!.ceil();
int ceil() => value.ceil();
/// Returns the integer obtained by discarding any fractional
/// digits from `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int truncate() => value!.truncate();
int truncate() => value.truncate();
/// Returns the double integer value closest to `this`.
///
... ... @@ -138,7 +133,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// The result is always a double.
/// If this is a numerically large integer, the result may be an infinite
/// double.
double roundToDouble() => value!.roundToDouble();
double roundToDouble() => value.roundToDouble();
/// Returns the greatest double integer value no greater than `this`.
///
... ... @@ -151,7 +146,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// The result is always a double.
/// If this is a numerically large integer, the result may be an infinite
/// double.
double floorToDouble() => value!.floorToDouble();
double floorToDouble() => value.floorToDouble();
/// Returns the least double integer value no smaller than `this`.
///
... ... @@ -164,7 +159,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// The result is always a double.
/// If this is a numerically large integer, the result may be an infinite
/// double.
double ceilToDouble() => value!.ceilToDouble();
double ceilToDouble() => value.ceilToDouble();
/// Returns the double integer value obtained by discarding any fractional
/// digits from the double value of `this`.
... ... @@ -179,7 +174,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// The result is always a double.
/// If this is a numerically large integer, the result may be an infinite
/// double.
double truncateToDouble() => value!.truncateToDouble();
double truncateToDouble() => value.truncateToDouble();
/// Returns this [num] clamped to be in the range [lowerLimit]-[upperLimit].
///
... ... @@ -190,17 +185,17 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// The arguments [lowerLimit] and [upperLimit] must form a valid range where
/// `lowerLimit.compareTo(upperLimit) <= 0`.
num clamp(num lowerLimit, num upperLimit) =>
value!.clamp(lowerLimit, upperLimit);
value.clamp(lowerLimit, upperLimit);
/// Truncates this [num] to an integer and returns the result as an [int]. */
int toInt() => value!.toInt();
int toInt() => value.toInt();
/// Return this [num] as a [double].
///
/// If the number is not representable as a [double], an
/// approximation is returned. For numerically large integers, the
/// approximation may be infinite.
double toDouble() => value!.toDouble();
double toDouble() => value.toDouble();
/// Returns a decimal-point string-representation of `this`.
///
... ... @@ -225,7 +220,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// 10000000000000000.toStringAsFixed(4); // 10000000000000000.0000
/// 5.25.toStringAsFixed(0); // 5
String toStringAsFixed(int fractionDigits) =>
value!.toStringAsFixed(fractionDigits);
value.toStringAsFixed(fractionDigits);
/// Returns an exponential string-representation of `this`.
///
... ... @@ -246,7 +241,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// 123456.toStringAsExponential(3); // 1.235e+5
/// 123.toStringAsExponential(0); // 1e+2
String toStringAsExponential([int? fractionDigits]) =>
value!.toStringAsExponential(fractionDigits);
value.toStringAsExponential(fractionDigits);
/// Converts `this` to a double and returns a string representation with
/// exactly [precision] significant digits.
... ... @@ -265,72 +260,137 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
/// 0.00000012345.toStringAsPrecision(15); // 1.23450000000000e-7
/// 0.0000012345.toStringAsPrecision(15); // 0.00000123450000000000
String toStringAsPrecision(int precision) =>
value!.toStringAsPrecision(precision);
value.toStringAsPrecision(precision);
}
class RxNum extends _BaseRxNum<num> {
RxNum(num initial) : super(initial);
extension RxnNumExt<T extends num> on Rx<T?> {
/// Multiplication operator.
num? operator *(num other) {
if (value != null) {
return value! * other;
}
}
num? operator +(num other) {
value += other;
return value;
/// Euclidean modulo operator.
///
/// Returns the remainder of the Euclidean division. The Euclidean division of
/// two integers `a` and `b` yields two integers `q` and `r` such that
/// `a == b * q + r` and `0 <= r < b.abs()`.
///
/// The Euclidean division is only defined for integers, but can be easily
/// extended to work with doubles. In that case `r` may have a non-integer
/// value, but it still verifies `0 <= r < |b|`.
///
/// The sign of the returned value `r` is always positive.
///
/// See [remainder] for the remainder of the truncating division.
num? operator %(num other) {
if (value != null) {
return value! % other;
}
}
/// Subtraction operator.
num? operator -(num other) {
value -= other;
return value;
/// Division operator.
double? operator /(num other) {
if (value != null) {
return value! / other;
}
}
}
class RxDouble extends _BaseRxNum<double?> {
RxDouble([double? initial]) : super(initial);
/// Truncating division operator.
///
/// If either operand is a [double] then the result of the truncating division
/// `a ~/ b` is equivalent to `(a / b).truncate().toInt()`.
///
/// If both operands are [int]s then `a ~/ b` performs the truncating
/// integer division.
int? operator ~/(num other) {
if (value != null) {
return value! ~/ other;
}
}
/// Addition operator.
RxDouble operator +(num other) {
value = value! + other;
return this;
/// Negate operator.
num? operator -() {
if (value != null) {
return -value!;
}
}
/// Subtraction operator.
RxDouble operator -(num other) {
value = value! - other;
return this;
/// Returns the remainder of the truncating division of `this` by [other].
///
/// The result `r` of this operation satisfies:
/// `this == (this ~/ other) * other + r`.
/// As a consequence the remainder `r` has the same sign as the divider
/// `this`.
num? remainder(num other) => value?.remainder(other);
/// Relational less than operator.
bool? operator <(num other) {
if (value != null) {
return value! < other;
}
}
/// Multiplication operator.
@override
double operator *(num other) => value! * other;
/// Relational less than or equal operator.
bool? operator <=(num other) {
if (value != null) {
return value! <= other;
}
}
@override
double operator %(num other) => value! % other;
/// Relational greater than operator.
bool? operator >(num other) {
if (value != null) {
return value! > other;
}
}
/// Division operator.
@override
double operator /(num other) => value! / other;
/// Relational greater than or equal operator.
bool? operator >=(num other) {
if (value != null) {
return value! >= other;
}
}
/// Truncating division operator.
/// True if the number is the double Not-a-Number value; otherwise, false.
bool? get isNaN => value?.isNaN;
/// True if the number is negative; otherwise, false.
///
/// The result of the truncating division `a ~/ b` is equivalent to
/// `(a / b).truncate()`.
@override
int operator ~/(num other) => value! ~/ other;
/// Negative numbers are those less than zero, and the double `-0.0`.
bool? get isNegative => value?.isNegative;
/// Negate operator. */
@override
double operator -() => -value!;
/// True if the number is positive infinity or negative infinity; otherwise,
/// false.
bool? get isInfinite => value?.isInfinite;
/// Returns the absolute value of this [double].
@override
double abs() => value!.abs();
/// True if the number is finite; otherwise, false.
///
/// The only non-finite numbers are NaN, positive infinity, and
/// negative infinity.
bool? get isFinite => value?.isFinite;
/// Returns the sign of the double's numerical value.
/// Returns the absolute value of this [num].
num? abs() => value?.abs();
/// Returns minus one, zero or plus one depending on the sign and
/// numerical value of the number.
///
/// Returns -1.0 if the value is less than zero,
/// +1.0 if the value is greater than zero,
/// and the value itself if it is -0.0, 0.0 or NaN.
@override
double get sign => value!.sign;
/// Returns minus one if the number is less than zero,
/// plus one if the number is greater than zero,
/// and zero if the number is equal to zero.
///
/// Returns NaN if the number is the double NaN value.
///
/// Returns a number of the same type as this number.
/// For doubles, `-0.0.sign == -0.0`.
/// The result satisfies:
///
/// n == n.sign * n.abs()
///
/// for all numbers `n` (except NaN, because NaN isn't `==` to itself).
num? get sign => value?.sign;
/// Returns the integer closest to `this`.
///
... ... @@ -338,163 +398,547 @@ class RxDouble extends _BaseRxNum<double?> {
/// `(3.5).round() == 4` and `(-3.5).round() == -4`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
@override
int round() => value!.round();
int? round() => value?.round();
/// Returns the greatest integer no greater than `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
@override
int floor() => value!.floor();
int? floor() => value?.floor();
/// Returns the least integer no smaller than `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
@override
int ceil() => value!.ceil();
int? ceil() => value?.ceil();
/// Returns the integer obtained by discarding any fractional
/// digits from `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
@override
int truncate() => value!.truncate();
int? truncate() => value?.truncate();
/// Returns the integer double value closest to `this`.
/// Returns the double integer value closest to `this`.
///
/// Rounds away from zero when there is no closest integer:
/// `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
/// If this is already an integer valued double, including `-0.0`, or it is a
/// non-finite double value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`,
/// and `-0.0` is therefore considered closer to negative numbers than `0.0`.
/// This means that for a value, `d` in the range `-0.5 < d < 0.0`,
/// the result is `-0.0`.
@override
double roundToDouble() => value!.roundToDouble();
///
/// The result is always a double.
/// If this is a numerically large integer, the result may be an infinite
/// double.
double? roundToDouble() => value?.roundToDouble();
/// Returns the greatest integer double value no greater than `this`.
/// Returns the greatest double integer value no greater than `this`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
/// If this is already an integer valued double, including `-0.0`, or it is a
/// non-finite double value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
/// A number `d` in the range `0.0 < d < 1.0` will return `0.0`.
@override
double floorToDouble() => value!.floorToDouble();
///
/// The result is always a double.
/// If this is a numerically large integer, the result may be an infinite
/// double.
double? floorToDouble() => value?.floorToDouble();
/// Returns the least integer double value no smaller than `this`.
/// Returns the least double integer value no smaller than `this`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
/// If this is already an integer valued double, including `-0.0`, or it is a
/// non-finite double value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
/// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`.
@override
double ceilToDouble() => value!.ceilToDouble();
///
/// The result is always a double.
/// If this is a numerically large integer, the result may be an infinite
/// double.
double? ceilToDouble() => value?.ceilToDouble();
/// Returns the integer double value obtained by discarding any fractional
/// digits from `this`.
/// Returns the double integer value obtained by discarding any fractional
/// digits from the double value of `this`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
/// If this is already an integer valued double, including `-0.0`, or it is a
/// non-finite double value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
/// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and
/// in the range `0.0 < d < 1.0` it will return 0.0.
@override
double truncateToDouble() => value!.truncateToDouble();
}
class RxInt extends _BaseRxNum<int> {
RxInt(int initial) : super(initial);
/// Addition operator.
RxInt operator +(int other) {
value = value + other;
return this;
}
/// Subtraction operator.
RxInt operator -(int other) {
value = value - other;
return this;
}
/// Bit-wise and operator.
///
/// Treating both `this` and [other] as sufficiently large two's component
/// integers, the result is a number with only the bits set that are set in
/// both `this` and [other]
///
/// If both operands are negative, the result is negative, otherwise
/// the result is non-negative.
int operator &(int other) => value & other;
/// The result is always a double.
/// If this is a numerically large integer, the result may be an infinite
/// double.
double? truncateToDouble() => value?.truncateToDouble();
/// Bit-wise or operator.
/// Returns this [num] clamped to be in the range [lowerLimit]-[upperLimit].
///
/// Treating both `this` and [other] as sufficiently large two's component
/// integers, the result is a number with the bits set that are set in either
/// of `this` and [other]
/// The comparison is done using [compareTo] and therefore takes `-0.0` into
/// account. This also implies that [double.nan] is treated as the maximal
/// double value.
///
/// If both operands are non-negative, the result is non-negative,
/// otherwise the result is negative.
int operator |(int other) => value | other;
/// The arguments [lowerLimit] and [upperLimit] must form a valid range where
/// `lowerLimit.compareTo(upperLimit) <= 0`.
num? clamp(num lowerLimit, num upperLimit) =>
value?.clamp(lowerLimit, upperLimit);
/// Bit-wise exclusive-or operator.
///
/// Treating both `this` and [other] as sufficiently large two's component
/// integers, the result is a number with the bits set that are set in one,
/// but not both, of `this` and [other]
///
/// If the operands have the same sign, the result is non-negative,
/// otherwise the result is negative.
int operator ^(int other) => value ^ other;
/// Truncates this [num] to an integer and returns the result as an [int]. */
int? toInt() => value?.toInt();
/// The bit-wise negate operator.
///
/// Treating `this` as a sufficiently large two's component integer,
/// the result is a number with the opposite bits set.
/// Return this [num] as a [double].
///
/// This maps any integer `x` to `-x - 1`.
int operator ~() => ~value;
/// If the number is not representable as a [double], an
/// approximation is returned. For numerically large integers, the
/// approximation may be infinite.
double? toDouble() => value?.toDouble();
/// Shift the bits of this integer to the left by [shiftAmount].
/// Returns a decimal-point string-representation of `this`.
///
/// Shifting to the left makes the number larger, effectively multiplying
/// the number by `pow(2, shiftIndex)`.
/// Converts `this` to a [double] before computing the string representation.
///
/// There is no limit on the size of the result. It may be relevant to
/// limit intermediate values by using the "and" operator with a suitable
/// mask.
/// If the absolute value of `this` is greater or equal to `10^21` then this
/// methods returns an exponential representation computed by
/// `this.toStringAsExponential()`. Otherwise the result
/// is the closest string representation with exactly [fractionDigits] digits
/// after the decimal point. If [fractionDigits] equals 0 then the decimal
/// point is omitted.
///
/// It is an error if [shiftAmount] is negative.
int operator <<(int shiftAmount) => value << shiftAmount;
/// Shift the bits of this integer to the right by [shiftAmount].
/// The parameter [fractionDigits] must be an integer satisfying:
/// `0 <= fractionDigits <= 20`.
///
/// Shifting to the right makes the number smaller and drops the least
/// significant bits, effectively doing an integer division by
///`pow(2, shiftIndex)`.
/// Examples:
///
/// It is an error if [shiftAmount] is negative.
int operator >>(int shiftAmount) => value >> shiftAmount;
/// 1.toStringAsFixed(3); // 1.000
/// (4321.12345678).toStringAsFixed(3); // 4321.123
/// (4321.12345678).toStringAsFixed(5); // 4321.12346
/// 123456789012345.toStringAsFixed(3); // 123456789012345.000
/// 10000000000000000.toStringAsFixed(4); // 10000000000000000.0000
/// 5.25.toStringAsFixed(0); // 5
String? toStringAsFixed(int fractionDigits) =>
value?.toStringAsFixed(fractionDigits);
/// Returns this integer to the power of [exponent] modulo [modulus].
/// Returns an exponential string-representation of `this`.
///
/// The [exponent] must be non-negative and [modulus] must be
/// positive.
int modPow(int exponent, int modulus) => value.modPow(exponent, modulus);
/// Returns the modular multiplicative inverse of this integer
/// modulo [modulus].
/// Converts `this` to a [double] before computing the string representation.
///
/// The [modulus] must be positive.
/// If [fractionDigits] is given then it must be an integer satisfying:
/// `0 <= fractionDigits <= 20`. In this case the string contains exactly
/// [fractionDigits] after the decimal point. Otherwise, without the
/// parameter, the returned string uses the shortest number of digits that
/// accurately represent [this].
///
/// It is an error if no modular inverse exists.
int modInverse(int modulus) => value.modInverse(modulus);
/// If [fractionDigits] equals 0 then the decimal point is omitted.
/// Examples:
///
/// 1.toStringAsExponential(); // 1e+0
/// 1.toStringAsExponential(3); // 1.000e+0
/// 123456.toStringAsExponential(); // 1.23456e+5
/// 123456.toStringAsExponential(3); // 1.235e+5
/// 123.toStringAsExponential(0); // 1e+2
String? toStringAsExponential([int? fractionDigits]) =>
value?.toStringAsExponential(fractionDigits);
/// Converts `this` to a double and returns a string representation with
/// exactly [precision] significant digits.
///
/// The parameter [precision] must be an integer satisfying:
/// `1 <= precision <= 21`.
///
/// Examples:
///
/// 1.toStringAsPrecision(2); // 1.0
/// 1e15.toStringAsPrecision(3); // 1.00e+15
/// 1234567.toStringAsPrecision(3); // 1.23e+6
/// 1234567.toStringAsPrecision(9); // 1234567.00
/// 12345678901234567890.toStringAsPrecision(20); // 12345678901234567168
/// 12345678901234567890.toStringAsPrecision(14); // 1.2345678901235e+19
/// 0.00000012345.toStringAsPrecision(15); // 1.23450000000000e-7
/// 0.0000012345.toStringAsPrecision(15); // 0.00000123450000000000
String? toStringAsPrecision(int precision) =>
value?.toStringAsPrecision(precision);
}
class RxNum extends Rx<num> {
RxNum(num initial) : super(initial);
num operator +(num other) {
value += other;
return value;
}
/// Subtraction operator.
num operator -(num other) {
value -= other;
return value;
}
}
class RxnNum extends Rx<num?> {
RxnNum(num initial) : super(initial);
num? operator +(num other) {
if (value != null) {
value = value! + other;
return value;
}
}
/// Subtraction operator.
num? operator -(num other) {
if (value != null) {
value = value! - other;
return value;
}
}
}
extension RxDoubleExt on Rx<double> {
/// Addition operator.
Rx<double> operator +(num other) {
value = value + other;
return this;
}
/// Subtraction operator.
Rx<double> operator -(num other) {
value = value - other;
return this;
}
/// Multiplication operator.
double operator *(num other) => value * other;
double operator %(num other) => value % other;
/// Division operator.
double operator /(num other) => value / other;
/// Truncating division operator.
///
/// The result of the truncating division `a ~/ b` is equivalent to
/// `(a / b).truncate()`.
int operator ~/(num other) => value ~/ other;
/// Negate operator. */
double operator -() => -value;
/// Returns the absolute value of this [double].
double abs() => value.abs();
/// Returns the sign of the double's numerical value.
///
/// Returns -1.0 if the value is less than zero,
/// +1.0 if the value is greater than zero,
/// and the value itself if it is -0.0, 0.0 or NaN.
double get sign => value.sign;
/// Returns the integer closest to `this`.
///
/// Rounds away from zero when there is no closest integer:
/// `(3.5).round() == 4` and `(-3.5).round() == -4`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int round() => value.round();
/// Returns the greatest integer no greater than `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int floor() => value.floor();
/// Returns the least integer no smaller than `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int ceil() => value.ceil();
/// Returns the integer obtained by discarding any fractional
/// digits from `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int truncate() => value.truncate();
/// Returns the integer double value closest to `this`.
///
/// Rounds away from zero when there is no closest integer:
/// `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`,
/// and `-0.0` is therefore considered closer to negative numbers than `0.0`.
/// This means that for a value, `d` in the range `-0.5 < d < 0.0`,
/// the result is `-0.0`.
double roundToDouble() => value.roundToDouble();
/// Returns the greatest integer double value no greater than `this`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
/// A number `d` in the range `0.0 < d < 1.0` will return `0.0`.
double floorToDouble() => value.floorToDouble();
/// Returns the least integer double value no smaller than `this`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
/// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`.
double ceilToDouble() => value.ceilToDouble();
/// Returns the integer double value obtained by discarding any fractional
/// digits from `this`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
/// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and
/// in the range `0.0 < d < 1.0` it will return 0.0.
double truncateToDouble() => value.truncateToDouble();
}
extension RxnDoubleExt on Rx<double?> {
/// Addition operator.
Rx<double?>? operator +(num other) {
if (value != null) {
value = value! + other;
return this;
}
}
/// Subtraction operator.
Rx<double?>? operator -(num other) {
if (value != null) {
value = value! + other;
return this;
}
}
/// Multiplication operator.
double? operator *(num other) {
if (value != null) {
return value! * other;
}
}
double? operator %(num other) {
if (value != null) {
return value! % other;
}
}
/// Division operator.
double? operator /(num other) {
if (value != null) {
return value! / other;
}
}
/// Truncating division operator.
///
/// The result of the truncating division `a ~/ b` is equivalent to
/// `(a / b).truncate()`.
int? operator ~/(num other) {
if (value != null) {
return value! ~/ other;
}
}
/// Negate operator. */
double? operator -() {
if (value != null) {
return -value!;
}
}
/// Returns the absolute value of this [double].
double? abs() {
return value?.abs();
}
/// Returns the sign of the double's numerical value.
///
/// Returns -1.0 if the value is less than zero,
/// +1.0 if the value is greater than zero,
/// and the value itself if it is -0.0, 0.0 or NaN.
double? get sign => value?.sign;
/// Returns the integer closest to `this`.
///
/// Rounds away from zero when there is no closest integer:
/// `(3.5).round() == 4` and `(-3.5).round() == -4`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int? round() => value?.round();
/// Returns the greatest integer no greater than `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int? floor() => value?.floor();
/// Returns the least integer no smaller than `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int? ceil() => value?.ceil();
/// Returns the integer obtained by discarding any fractional
/// digits from `this`.
///
/// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
int? truncate() => value?.truncate();
/// Returns the integer double value closest to `this`.
///
/// Rounds away from zero when there is no closest integer:
/// `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`,
/// and `-0.0` is therefore considered closer to negative numbers than `0.0`.
/// This means that for a value, `d` in the range `-0.5 < d < 0.0`,
/// the result is `-0.0`.
double? roundToDouble() => value?.roundToDouble();
/// Returns the greatest integer double value no greater than `this`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
/// A number `d` in the range `0.0 < d < 1.0` will return `0.0`.
double? floorToDouble() => value?.floorToDouble();
/// Returns the least integer double value no smaller than `this`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
/// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`.
double? ceilToDouble() => value?.ceilToDouble();
/// Returns the integer double value obtained by discarding any fractional
/// digits from `this`.
///
/// If this is already an integer valued double, including `-0.0`, or it is
/// not a finite value, the value is returned unmodified.
///
/// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
/// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and
/// in the range `0.0 < d < 1.0` it will return 0.0.
double? truncateToDouble() => value?.truncateToDouble();
}
class RxDouble extends Rx<double> {
RxDouble(double initial) : super(initial);
}
class RxnDouble extends Rx<double?> {
RxnDouble([double? initial]) : super(initial);
}
class RxInt extends Rx<int> {
RxInt(int initial) : super(initial);
}
class RxnInt extends Rx<int?> {
RxnInt([int? initial]) : super(initial);
}
extension RxIntExt on Rx<int> {
/// Addition operator.
Rx<int> operator +(int other) {
value = value + other;
return this;
}
/// Subtraction operator.
Rx<int> operator -(int other) {
value = value - other;
return this;
}
/// Bit-wise and operator.
///
/// Treating both `this` and [other] as sufficiently large two's component
/// integers, the result is a number with only the bits set that are set in
/// both `this` and [other]
///
/// If both operands are negative, the result is negative, otherwise
/// the result is non-negative.
int operator &(int other) => value & other;
/// Bit-wise or operator.
///
/// Treating both `this` and [other] as sufficiently large two's component
/// integers, the result is a number with the bits set that are set in either
/// of `this` and [other]
///
/// If both operands are non-negative, the result is non-negative,
/// otherwise the result is negative.
int operator |(int other) => value | other;
/// Bit-wise exclusive-or operator.
///
/// Treating both `this` and [other] as sufficiently large two's component
/// integers, the result is a number with the bits set that are set in one,
/// but not both, of `this` and [other]
///
/// If the operands have the same sign, the result is non-negative,
/// otherwise the result is negative.
int operator ^(int other) => value ^ other;
/// The bit-wise negate operator.
///
/// Treating `this` as a sufficiently large two's component integer,
/// the result is a number with the opposite bits set.
///
/// This maps any integer `x` to `-x - 1`.
int operator ~() => ~value;
/// Shift the bits of this integer to the left by [shiftAmount].
///
/// Shifting to the left makes the number larger, effectively multiplying
/// the number by `pow(2, shiftIndex)`.
///
/// There is no limit on the size of the result. It may be relevant to
/// limit intermediate values by using the "and" operator with a suitable
/// mask.
///
/// It is an error if [shiftAmount] is negative.
int operator <<(int shiftAmount) => value << shiftAmount;
/// Shift the bits of this integer to the right by [shiftAmount].
///
/// Shifting to the right makes the number smaller and drops the least
/// significant bits, effectively doing an integer division by
///`pow(2, shiftIndex)`.
///
/// It is an error if [shiftAmount] is negative.
int operator >>(int shiftAmount) => value >> shiftAmount;
/// Returns this integer to the power of [exponent] modulo [modulus].
///
/// The [exponent] must be non-negative and [modulus] must be
/// positive.
int modPow(int exponent, int modulus) => value.modPow(exponent, modulus);
/// Returns the modular multiplicative inverse of this integer
/// modulo [modulus].
///
/// The [modulus] must be positive.
///
/// It is an error if no modular inverse exists.
int modInverse(int modulus) => value.modInverse(modulus);
/// Returns the greatest common divisor of this integer and [other].
///
... ... @@ -593,51 +1037,293 @@ class RxInt extends _BaseRxNum<int> {
///
/// The result of negating an integer always has the opposite sign, except
/// for zero, which is its own negation.
@override
int operator -() => -value;
/// Returns the absolute value of this integer.
///
/// For any integer `x`, the result is the same as `x < 0 ? -x : x`.
@override
int abs() => value.abs();
/// Returns the sign of this integer.
///
/// Returns 0 for zero, -1 for values less than zero and
/// +1 for values greater than zero.
@override
int get sign => value.sign;
/// Returns `this`.
@override
int round() => value.round();
/// Returns `this`.
@override
int floor() => value.floor();
/// Returns `this`.
@override
int ceil() => value.ceil();
/// Returns `this`.
@override
int truncate() => value.truncate();
/// Returns `this.toDouble()`.
@override
double roundToDouble() => value.roundToDouble();
/// Returns `this.toDouble()`.
@override
double floorToDouble() => value.floorToDouble();
/// Returns `this.toDouble()`.
@override
double ceilToDouble() => value.ceilToDouble();
/// Returns `this.toDouble()`.
@override
double truncateToDouble() => value.truncateToDouble();
}
extension RxnIntExt on Rx<int?> {
/// Addition operator.
Rx<int?>? operator +(int other) {
if (value != null) {
value = value! + other;
return this;
}
}
/// Subtraction operator.
Rx<int?>? operator -(int other) {
if (value != null) {
value = value! - other;
return this;
}
}
/// Bit-wise and operator.
///
/// Treating both `this` and [other] as sufficiently large two's component
/// integers, the result is a number with only the bits set that are set in
/// both `this` and [other]
///
/// If both operands are negative, the result is negative, otherwise
/// the result is non-negative.
int? operator &(int other) {
if (value != null) {
return value! & other;
}
}
/// Bit-wise or operator.
///
/// Treating both `this` and [other] as sufficiently large two's component
/// integers, the result is a number with the bits set that are set in either
/// of `this` and [other]
///
/// If both operands are non-negative, the result is non-negative,
/// otherwise the result is negative.
int? operator |(int other) {
if (value != null) {
return value! | other;
}
}
/// Bit-wise exclusive-or operator.
///
/// Treating both `this` and [other] as sufficiently large two's component
/// integers, the result is a number with the bits set that are set in one,
/// but not both, of `this` and [other]
///
/// If the operands have the same sign, the result is non-negative,
/// otherwise the result is negative.
int? operator ^(int other) {
if (value != null) {
return value! ^ other;
}
}
/// The bit-wise negate operator.
///
/// Treating `this` as a sufficiently large two's component integer,
/// the result is a number with the opposite bits set.
///
/// This maps any integer `x` to `-x - 1`.
int? operator ~() {
if (value != null) {
return ~value!;
}
}
/// Shift the bits of this integer to the left by [shiftAmount].
///
/// Shifting to the left makes the number larger, effectively multiplying
/// the number by `pow(2, shiftIndex)`.
///
/// There is no limit on the size of the result. It may be relevant to
/// limit intermediate values by using the "and" operator with a suitable
/// mask.
///
/// It is an error if [shiftAmount] is negative.
int? operator <<(int shiftAmount) {
if (value != null) {
return value! << shiftAmount;
}
}
/// Shift the bits of this integer to the right by [shiftAmount].
///
/// Shifting to the right makes the number smaller and drops the least
/// significant bits, effectively doing an integer division by
///`pow(2, shiftIndex)`.
///
/// It is an error if [shiftAmount] is negative.
int? operator >>(int shiftAmount) {
if (value != null) {
return value! >> shiftAmount;
}
}
/// Returns this integer to the power of [exponent] modulo [modulus].
///
/// The [exponent] must be non-negative and [modulus] must be
/// positive.
int? modPow(int exponent, int modulus) => value?.modPow(exponent, modulus);
/// Returns the modular multiplicative inverse of this integer
/// modulo [modulus].
///
/// The [modulus] must be positive.
///
/// It is an error if no modular inverse exists.
int? modInverse(int modulus) => value?.modInverse(modulus);
/// Returns the greatest common divisor of this integer and [other].
///
/// If either number is non-zero, the result is the numerically greatest
/// integer dividing both `this` and `other`.
///
/// The greatest common divisor is independent of the order,
/// so `x.gcd(y)` is always the same as `y.gcd(x)`.
///
/// For any integer `x`, `x.gcd(x)` is `x.abs()`.
///
/// If both `this` and `other` is zero, the result is also zero.
int? gcd(int other) => value?.gcd(other);
/// Returns true if and only if this integer is even.
bool? get isEven => value?.isEven;
/// Returns true if and only if this integer is odd.
bool? get isOdd => value?.isOdd;
/// Returns the minimum number of bits required to store this integer.
///
/// The number of bits excludes the sign bit, which gives the natural length
/// for non-negative (unsigned) values. Negative values are complemented to
/// return the bit position of the first bit that differs from the sign bit.
///
/// To find the number of bits needed to store the value as a signed value,
/// add one, i.e. use `x.bitLength + 1`.
/// ```
/// x.bitLength == (-x-1).bitLength
///
/// 3.bitLength == 2; // 00000011
/// 2.bitLength == 2; // 00000010
/// 1.bitLength == 1; // 00000001
/// 0.bitLength == 0; // 00000000
/// (-1).bitLength == 0; // 11111111
/// (-2).bitLength == 1; // 11111110
/// (-3).bitLength == 2; // 11111101
/// (-4).bitLength == 2; // 11111100
/// ```
int? get bitLength => value?.bitLength;
/// Returns the least significant [width] bits of this integer as a
/// non-negative number (i.e. unsigned representation). The returned value
/// has zeros in all bit positions higher than [width].
/// ```
/// (-1).toUnsigned(5) == 31 // 11111111 -> 00011111
/// ```
/// This operation can be used to simulate arithmetic from low level
/// languages.
/// For example, to increment an 8 bit quantity:
/// ```
/// q = (q + 1).toUnsigned(8);
/// ```
/// `q` will count from `0` up to `255` and then wrap around to `0`.
///
/// If the input fits in [width] bits without truncation, the result is the
/// same as the input. The minimum width needed to avoid truncation of `x` is
/// given by `x.bitLength`, i.e.
/// ```
/// x == x.toUnsigned(x.bitLength);
/// ```
int? toUnsigned(int width) => value?.toUnsigned(width);
/// Returns the least significant [width] bits of this integer, extending the
/// highest retained bit to the sign. This is the same as truncating the
/// value to fit in [width] bits using an signed 2-s complement
/// representation.
/// The returned value has the same bit value in all positions higher than
/// [width].
///
/// ```
/// V--sign bit-V
/// 16.toSigned(5) == -16 // 00010000 -> 11110000
/// 239.toSigned(5) == 15 // 11101111 -> 00001111
/// ^ ^
/// ```
/// This operation can be used to simulate arithmetic from low level
/// languages.
/// For example, to increment an 8 bit signed quantity:
/// ```
/// q = (q + 1).toSigned(8);
/// ```
/// `q` will count from `0` up to `127`, wrap to `-128` and count back up to
/// `127`.
///
/// If the input value fits in [width] bits without truncation, the result is
/// the same as the input. The minimum width needed to avoid truncation
/// of `x` is `x.bitLength + 1`, i.e.
/// ```
/// x == x.toSigned(x.bitLength + 1);
/// ```
int? toSigned(int width) => value?.toSigned(width);
/// Return the negative value of this integer.
///
/// The result of negating an integer always has the opposite sign, except
/// for zero, which is its own negation.
int? operator -() {
if (value != null) {
return -value!;
}
}
/// Returns the absolute value of this integer.
///
/// For any integer `x`, the result is the same as `x < 0 ? -x : x`.
int? abs() => value?.abs();
/// Returns the sign of this integer.
///
/// Returns 0 for zero, -1 for values less than zero and
/// +1 for values greater than zero.
int? get sign => value?.sign;
/// Returns `this`.
int? round() => value?.round();
/// Returns `this`.
int? floor() => value?.floor();
/// Returns `this`.
int? ceil() => value?.ceil();
/// Returns `this`.
int? truncate() => value?.truncate();
/// Returns `this.toDouble()`.
double? roundToDouble() => value?.roundToDouble();
/// Returns `this.toDouble()`.
double? floorToDouble() => value?.floorToDouble();
/// Returns `this.toDouble()`.
double? ceilToDouble() => value?.ceilToDouble();
/// Returns `this.toDouble()`.
double? truncateToDouble() => value?.truncateToDouble();
}
... ...
part of rx_types;
extension RxStringExt on Rx<String> {
String operator +(String val) => _value + val;
int compareTo(String other) {
return value.compareTo(other);
}
/// Returns true if this string ends with [other]. For example:
///
/// 'Dart'.endsWith('t'); // true
bool endsWith(String other) {
return value.endsWith(other);
}
/// Returns true if this string starts with a match of [pattern].
bool startsWith(Pattern pattern, [int index = 0]) {
return value.startsWith(pattern, index);
}
/// Returns the position of the first match of [pattern] in this string
int indexOf(Pattern pattern, [int start = 0]) {
return value.indexOf(pattern, start);
}
/// Returns the starting position of the last match [pattern] in this string,
/// searching backward starting at [start], inclusive:
int lastIndexOf(Pattern pattern, [int? start]) {
return value.lastIndexOf(pattern, start);
}
/// Returns true if this string is empty.
bool get isEmpty => value.isEmpty;
/// Returns true if this string is not empty.
bool get isNotEmpty => !isEmpty;
/// Returns the substring of this string that extends from [startIndex],
/// inclusive, to [endIndex], exclusive
String substring(int startIndex, [int? endIndex]) {
return value.substring(startIndex, endIndex);
}
/// Returns the string without any leading and trailing whitespace.
String trim() {
return value.trim();
}
/// Returns the string without any leading whitespace.
///
/// As [trim], but only removes leading whitespace.
String trimLeft() {
return value.trimLeft();
}
/// Returns the string without any trailing whitespace.
///
/// As [trim], but only removes trailing whitespace.
String trimRight() {
return value.trimRight();
}
/// Pads this string on the left if it is shorter than [width].
///
/// Return a new string that prepends [padding] onto this string
/// one time for each position the length is less than [width].
String padLeft(int width, [String padding = ' ']) {
return value.padLeft(width, padding);
}
/// Pads this string on the right if it is shorter than [width].
/// Return a new string that appends [padding] after this string
/// one time for each position the length is less than [width].
String padRight(int width, [String padding = ' ']) {
return value.padRight(width, padding);
}
/// Returns true if this string contains a match of [other]:
bool contains(Pattern other, [int startIndex = 0]) {
return value.contains(other, startIndex);
}
/// Replaces all substrings that match [from] with [replace].
String replaceAll(Pattern from, String replace) {
return value.replaceAll(from, replace);
}
/// Splits the string at matches of [pattern] and returns a list
/// of substrings.
List<String> split(Pattern pattern) {
return value.split(pattern);
}
/// Returns an unmodifiable list of the UTF-16 code units of this string.
List<int> get codeUnits => value.codeUnits;
/// Returns an [Iterable] of Unicode code-points of this string.
///
/// If the string contains surrogate pairs, they are combined and returned
/// as one integer by this iterator. Unmatched surrogate halves are treated
/// like valid 16-bit code-units.
Runes get runes => value.runes;
/// Converts all characters in this string to lower case.
/// If the string is already in all lower case, this method returns `this`.
String toLowerCase() {
return value.toLowerCase();
}
/// Converts all characters in this string to upper case.
/// If the string is already in all upper case, this method returns `this`.
String toUpperCase() {
return value.toUpperCase();
}
Iterable<Match> allMatches(String string, [int start = 0]) {
return value.allMatches(string, start);
}
Match? matchAsPrefix(String string, [int start = 0]) {
return value.matchAsPrefix(string, start);
}
}
extension RxnStringExt on Rx<String?> {
String operator +(String val) => (_value ?? '') + val;
int? compareTo(String other) {
return value?.compareTo(other);
}
/// Returns true if this string ends with [other]. For example:
///
/// 'Dart'.endsWith('t'); // true
bool? endsWith(String other) {
return value?.endsWith(other);
}
/// Returns true if this string starts with a match of [pattern].
bool? startsWith(Pattern pattern, [int index = 0]) {
return value?.startsWith(pattern, index);
}
/// Returns the position of the first match of [pattern] in this string
int? indexOf(Pattern pattern, [int start = 0]) {
return value?.indexOf(pattern, start);
}
/// Returns the starting position of the last match [pattern] in this string,
/// searching backward starting at [start], inclusive:
int? lastIndexOf(Pattern pattern, [int? start]) {
return value?.lastIndexOf(pattern, start);
}
/// Returns true if this string is empty.
bool? get isEmpty => value?.isEmpty;
/// Returns true if this string is not empty.
bool? get isNotEmpty => value?.isNotEmpty;
/// Returns the substring of this string that extends from [startIndex],
/// inclusive, to [endIndex], exclusive
String? substring(int startIndex, [int? endIndex]) {
return value?.substring(startIndex, endIndex);
}
/// Returns the string without any leading and trailing whitespace.
String? trim() {
return value?.trim();
}
/// Returns the string without any leading whitespace.
///
/// As [trim], but only removes leading whitespace.
String? trimLeft() {
return value?.trimLeft();
}
/// Returns the string without any trailing whitespace.
///
/// As [trim], but only removes trailing whitespace.
String? trimRight() {
return value?.trimRight();
}
/// Pads this string on the left if it is shorter than [width].
///
/// Return a new string that prepends [padding] onto this string
/// one time for each position the length is less than [width].
String? padLeft(int width, [String padding = ' ']) {
return value?.padLeft(width, padding);
}
/// Pads this string on the right if it is shorter than [width].
/// Return a new string that appends [padding] after this string
/// one time for each position the length is less than [width].
String? padRight(int width, [String padding = ' ']) {
return value?.padRight(width, padding);
}
/// Returns true if this string contains a match of [other]:
bool? contains(Pattern other, [int startIndex = 0]) {
return value?.contains(other, startIndex);
}
/// Replaces all substrings that match [from] with [replace].
String? replaceAll(Pattern from, String replace) {
return value?.replaceAll(from, replace);
}
/// Splits the string at matches of [pattern] and returns a list
/// of substrings.
List<String>? split(Pattern pattern) {
return value?.split(pattern);
}
/// Returns an unmodifiable list of the UTF-16 code units of this string.
List<int>? get codeUnits => value?.codeUnits;
/// Returns an [Iterable] of Unicode code-points of this string.
///
/// If the string contains surrogate pairs, they are combined and returned
/// as one integer by this iterator. Unmatched surrogate halves are treated
/// like valid 16-bit code-units.
Runes? get runes => value?.runes;
/// Converts all characters in this string to lower case.
/// If the string is already in all lower case, this method returns `this`.
String? toLowerCase() {
return value?.toLowerCase();
}
/// Converts all characters in this string to upper case.
/// If the string is already in all upper case, this method returns `this`.
String? toUpperCase() {
return value?.toUpperCase();
}
Iterable<Match>? allMatches(String string, [int start = 0]) {
return value?.allMatches(string, start);
}
Match? matchAsPrefix(String string, [int start = 0]) {
return value?.matchAsPrefix(string, start);
}
}
/// Rx class for `String` Type.
class RxString extends Rx<String> implements Comparable<String>, Pattern {
RxString(String initial) : super(initial);
@override
Iterable<Match> allMatches(String string, [int start = 0]) {
return value.allMatches(string, start);
}
@override
Match? matchAsPrefix(String string, [int start = 0]) {
return value.matchAsPrefix(string, start);
}
@override
int compareTo(String other) {
return value.compareTo(other);
}
}
/// Rx class for `String` Type.
class RxnString extends Rx<String?> implements Comparable<String>, Pattern {
RxnString(String? initial) : super(initial);
@override
Iterable<Match> allMatches(String string, [int start = 0]) {
return value!.allMatches(string, start);
}
@override
Match? matchAsPrefix(String string, [int start = 0]) {
return value!.matchAsPrefix(string, start);
}
@override
int compareTo(String other) {
return value!.compareTo(other);
}
}
... ...
... ... @@ -10,6 +10,7 @@ import '../rx_typedefs/rx_typedefs.dart';
part 'rx_core/rx_impl.dart';
part 'rx_core/rx_interface.dart';
part 'rx_core/rx_num.dart';
part 'rx_core/rx_string.dart';
part 'rx_iterables/rx_list.dart';
part 'rx_iterables/rx_set.dart';
... ...
... ... @@ -104,24 +104,3 @@ class ObxValue<T extends RxInterface> extends ObxWidget {
@override
Widget build() => builder(data);
}
/// Similar to Obx, but manages a local state.
/// Pass the initial data in constructor.
/// Useful for simple local states, like toggles, visibility, themes,
/// button states, etc.
/// Sample:
/// ObxValue((data) => Switch(
/// value: data.value,
/// onChanged: (flag) => data.value = flag,
/// ),
/// false.obs,
/// ),
class RxValue<T> extends ObxWidget {
final Widget Function(T? data) builder;
final Rx<T> data = Rx<T>();
RxValue(this.builder, {Key? key}) : super(key: key);
@override
Widget build() => builder(data.value);
}
... ...
name: get
description: Open screens/snackbars/dialogs without context, manage states and inject dependencies easily with GetX.
version: 4.0.0-nullsafety.2
version: 4.0.0
homepage: https://github.com/jonataslaw/getx
environment:
... ...
... ... @@ -129,4 +129,36 @@ void main() {
await Future.delayed(Duration(milliseconds: 100));
expect(3, timesCalled);
});
test('Rx String with non null values', () async {
final reactiveString = Rx<String>("abc");
var currentString;
reactiveString.listen((newString) {
currentString = newString;
});
expect(reactiveString.endsWith("c"), true);
// we call 3
reactiveString("b");
await Future.delayed(Duration.zero);
expect(currentString, "b");
});
test('Rx String with null values', () async {
var reactiveString = Rx<String?>(null);
var currentString;
reactiveString.listen((newString) {
currentString = newString;
});
// we call 3
reactiveString("abc");
await Future.delayed(Duration.zero);
expect(reactiveString.endsWith("c"), true);
expect(currentString, "abc");
});
}
... ...