feat(types): add object, string, datetime, iterable extensions
This commit is contained in:
parent
46f5960d43
commit
5f7efddb86
@ -77,3 +77,72 @@ final Result<TodoModel, AppError> todo1 = await requestTodo();
|
||||
// In Flutter:
|
||||
todo1.either(buildWidgetWithTodo, buildSizedBox);
|
||||
```
|
||||
|
||||
## Pair\<L, R>
|
||||
|
||||
**Pair** is a simple object which contains pair of two values.
|
||||
|
||||
```dart
|
||||
const Pair<int, int> myPair = Pair(42, 16);
|
||||
print(myPair.left); // prints '42'
|
||||
print(myPair.right); // prints '16'
|
||||
print(myPair); // prints '(42, 16)'
|
||||
final List<int> myList = myPair.toList();
|
||||
print(myList); // prints '[42, 16]'
|
||||
```
|
||||
|
||||
## Extensions
|
||||
|
||||
This package also provides extensions for Dart types.
|
||||
|
||||
- Object
|
||||
- isNull
|
||||
- isNotNull
|
||||
- log
|
||||
- Iterable
|
||||
- isNullOrEmpty
|
||||
- isNotNullOrEmpty
|
||||
- For bytes iterables
|
||||
- toTypedList
|
||||
- toStr
|
||||
- String
|
||||
- isNullOrEmpty
|
||||
- isNotNullOrEmpty
|
||||
- toBytes
|
||||
|
||||
String 🔁 Uint8List works with encoding:
|
||||
|
||||
```dart
|
||||
const String myString = 'abc';
|
||||
final Uint8List bytes = myString.toBytes(from : Encoding.utf16);
|
||||
print(bytes.toStr(to : Encoding.utf16)); // prints 'abc'
|
||||
```
|
||||
|
||||
- DateTime
|
||||
- fromSecondsSinceEpoch
|
||||
- secondsSinceEpoch
|
||||
- timestamp
|
||||
- tomorrow
|
||||
- yesterday
|
||||
- today
|
||||
- add/sub/set
|
||||
- nextDay
|
||||
- previousDay
|
||||
- nextMonth
|
||||
- previousMonth
|
||||
- nextYear
|
||||
- previousYear
|
||||
- nextWeek
|
||||
- previousWeek
|
||||
- isFuture
|
||||
- isPast
|
||||
- isLeapYear
|
||||
- format
|
||||
- operators
|
||||
|
||||
The date formatter works with `String` formatter:
|
||||
|
||||
```dart
|
||||
final DateTime date = DateTime(1999, 6, 30);
|
||||
print(date.format([dd, '/', mm, '/', yy])); // prints '30/06/99'
|
||||
```
|
||||
|
@ -0,0 +1,620 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// ignore_for_file: constant_identifier_names
|
||||
|
||||
/// Outputs year as four digits
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989), [yyyy]);
|
||||
/// // => 1989
|
||||
/// ```
|
||||
const String yyyy = 'yyyy';
|
||||
|
||||
/// Outputs year as two digits
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989), [yy]);
|
||||
/// // => 89
|
||||
/// ```
|
||||
const String yy = 'yy';
|
||||
|
||||
/// Outputs month as two digits
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 11), [mm]);
|
||||
/// // => 11
|
||||
/// formatDate(DateTime(1989, 5), [mm]);
|
||||
/// // => 05
|
||||
/// ```
|
||||
const String mm = 'mm';
|
||||
|
||||
/// Outputs month compactly
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 11), [mm]);
|
||||
/// // => 11
|
||||
/// formatDate(DateTime(1989, 5), [m]);
|
||||
/// // => 5
|
||||
/// ```
|
||||
const String m = 'm';
|
||||
|
||||
/// Outputs day as two digits
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 2, 21), [dd]);
|
||||
/// // => 21
|
||||
/// formatDate(DateTime(1989, 2, 5), [dd]);
|
||||
/// // => 05
|
||||
/// ```
|
||||
const String dd = 'dd';
|
||||
|
||||
/// Outputs day compactly
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 2, 21), [d]);
|
||||
/// // => 21
|
||||
/// formatDate(DateTime(1989, 2, 5), [d]);
|
||||
/// // => 5
|
||||
/// ```
|
||||
const String d = 'd';
|
||||
|
||||
/// Outputs week in month
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 2, 21), [w]);
|
||||
/// // => 4
|
||||
/// ```
|
||||
const String w = 'w';
|
||||
|
||||
/// Outputs week in year as two digits
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 12, 31), [W]);
|
||||
/// // => 53
|
||||
/// formatDate(DateTime(1989, 2, 21), [W]);
|
||||
/// // => 08
|
||||
/// ```
|
||||
const String WW = 'WW';
|
||||
|
||||
/// Outputs week in year compactly
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 2, 21), [W]);
|
||||
/// // => 8
|
||||
/// ```
|
||||
const String W = 'W';
|
||||
|
||||
/// Outputs hour (0 - 11) as two digits
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15), [hh]);
|
||||
/// // => 03
|
||||
/// ```
|
||||
const String hh = 'hh';
|
||||
|
||||
/// Outputs hour (0 - 11) compactly
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15), [h]);
|
||||
/// // => 3
|
||||
/// ```
|
||||
const String h = 'h';
|
||||
|
||||
/// Outputs hour (0 to 23) as two digits
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15), [HH]);
|
||||
/// // => 15
|
||||
/// ```
|
||||
const String HH = 'HH';
|
||||
|
||||
/// Outputs hour (0 to 23) compactly
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 5), [H]);
|
||||
/// // => 5
|
||||
/// ```
|
||||
const String H = 'H';
|
||||
|
||||
/// Outputs minute as two digits
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40), [nn]);
|
||||
/// // => 40
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 4), [nn]);
|
||||
/// // => 04
|
||||
/// ```
|
||||
const String nn = 'nn';
|
||||
|
||||
/// Outputs minute compactly
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 4), [n]);
|
||||
/// // => 4
|
||||
/// ```
|
||||
const String n = 'n';
|
||||
|
||||
/// Outputs second as two digits
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10), [ss]);
|
||||
/// // => 10
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 5), [ss]);
|
||||
/// // => 05
|
||||
/// ```
|
||||
const String ss = 'ss';
|
||||
|
||||
/// Outputs second compactly
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 5), [s]);
|
||||
/// // => 5
|
||||
/// ```
|
||||
const String s = 's';
|
||||
|
||||
/// Outputs millisecond as three digits
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 999), [SSS]);
|
||||
/// // => 999
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 99), [SS]);
|
||||
/// // => 099
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0), [SS]);
|
||||
/// // => 009
|
||||
/// ```
|
||||
const String SSS = 'SSS';
|
||||
|
||||
/// Outputs millisecond compactly
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 999), [SSS]);
|
||||
/// // => 999
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 99), [SS]);
|
||||
/// // => 99
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 9), [SS]);
|
||||
/// // => 9
|
||||
/// ```
|
||||
const String S = 'S';
|
||||
|
||||
/// Outputs microsecond as three digits
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 999), [uuu]);
|
||||
/// // => 999
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 99), [uuu]);
|
||||
/// // => 099
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 9), [uuu]);
|
||||
/// // => 009
|
||||
/// ```
|
||||
const String uuu = 'uuu';
|
||||
|
||||
/// Outputs millisecond compactly
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 999), [u]);
|
||||
/// // => 999
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 99), [u]);
|
||||
/// // => 99
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40, 10, 0, 9), [u]);
|
||||
/// // => 9
|
||||
/// ```
|
||||
const String u = 'u';
|
||||
|
||||
/// Outputs timezone as time offset
|
||||
const String z = 'z';
|
||||
const String Z = 'Z';
|
||||
|
||||
/// Escape delimiters to be used as normal string.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// formatDate(DateTime(1989, 02, 1, 15, 40), [HH,'\\h',nn]);
|
||||
/// // => 15h40
|
||||
///```
|
||||
const String escape = r'\';
|
||||
|
||||
extension DateTimeExtension on DateTime {
|
||||
/// {@template unix}
|
||||
/// Number of seconds since epoch time / A.K.A Unix timestamp
|
||||
///
|
||||
/// The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the
|
||||
/// number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT),
|
||||
/// not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
|
||||
/// Literally speaking the epoch is Unix time 0 (midnight 1/1/1970).
|
||||
/// {@endtemplate}
|
||||
static DateTime fromSecondsSinceEpoch(
|
||||
int secondsSinceEpoch, {
|
||||
bool isUtc = false,
|
||||
}) =>
|
||||
DateTime.fromMillisecondsSinceEpoch(
|
||||
secondsSinceEpoch * 1000,
|
||||
isUtc: isUtc,
|
||||
);
|
||||
|
||||
/// {@macro unix}
|
||||
int get secondsSinceEpoch => millisecondsSinceEpoch ~/ 1000;
|
||||
|
||||
/// Get the numer of milliseconds since epoch
|
||||
int get timestamp => millisecondsSinceEpoch;
|
||||
|
||||
/// Tomorrow at same hour / minute / second than now
|
||||
static DateTime get tomorrow => DateTime.now().nextDay;
|
||||
|
||||
/// Yesterday at same hour / minute / second than now
|
||||
static DateTime get yesterday => DateTime.now().previousDay;
|
||||
|
||||
/// Current date (Same as [DateTime.now])
|
||||
static DateTime get today => DateTime.now();
|
||||
|
||||
/// Subtracts a [Duration] from this [DateTime]
|
||||
DateTime sub(Duration duration) => add(Duration.zero - duration);
|
||||
|
||||
/// Add a certain amount of milliseconds to this date
|
||||
DateTime addMilliseconds(int amount) => add(Duration(milliseconds: amount));
|
||||
|
||||
/// Add a certain amount of microseconds to this date
|
||||
DateTime addMicroseconds(int amount) => add(Duration(microseconds: amount));
|
||||
|
||||
/// Add a certain amount of minutes to this date
|
||||
DateTime addMinutes(int amount, {bool ignoreDaylightSavings = false}) =>
|
||||
ignoreDaylightSavings
|
||||
? DateTime(
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute + amount,
|
||||
second,
|
||||
millisecond,
|
||||
microsecond,
|
||||
)
|
||||
: add(Duration(minutes: amount));
|
||||
|
||||
/// Add a certain amount of hours to this date
|
||||
DateTime addHours(int amount, {bool ignoreDaylightSavings = false}) =>
|
||||
ignoreDaylightSavings
|
||||
? DateTime(
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour + amount,
|
||||
minute,
|
||||
second,
|
||||
millisecond,
|
||||
microsecond,
|
||||
)
|
||||
: add(Duration(hours: amount));
|
||||
|
||||
/// Add a certain amount of days to this date
|
||||
DateTime addDays(int amount, {bool ignoreDaylightSavings = false}) =>
|
||||
ignoreDaylightSavings
|
||||
? DateTime(
|
||||
year,
|
||||
month,
|
||||
day + amount,
|
||||
hour,
|
||||
minute,
|
||||
second,
|
||||
millisecond,
|
||||
microsecond,
|
||||
)
|
||||
: add(Duration(days: amount));
|
||||
|
||||
/// The day after this [DateTime]
|
||||
DateTime get nextDay => addDays(1);
|
||||
|
||||
/// The day previous this [DateTime]
|
||||
DateTime get previousDay => addDays(-1);
|
||||
|
||||
/// The month after this [DateTime]
|
||||
DateTime get nextMonth => setMonth(month + 1);
|
||||
|
||||
/// The month previous this [DateTime]
|
||||
DateTime get previousMonth => setMonth(month - 1);
|
||||
|
||||
/// The year after this [DateTime]
|
||||
DateTime get nextYear => setYear(year + 1);
|
||||
|
||||
/// The year previous this [DateTime]
|
||||
DateTime get previousYear => setYear(year - 1);
|
||||
|
||||
/// The week after this [DateTime]
|
||||
DateTime get nextWeek => addDays(7);
|
||||
|
||||
/// The week previous this [DateTime]
|
||||
DateTime get previousWeek => addDays(-7);
|
||||
|
||||
/// Return true if this date [isAfter] [DateTime.now]
|
||||
bool get isFuture => isAfter(DateTime.now());
|
||||
|
||||
/// Return true if this date [isBefore] [DateTime.now]
|
||||
bool get isPast => isBefore(DateTime.now());
|
||||
|
||||
/// Is the given date in the leap year?
|
||||
bool get isLeapYear => year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||
|
||||
/// Change [year] of this date
|
||||
DateTime setYear(
|
||||
int year, [
|
||||
int? month,
|
||||
int? day,
|
||||
int? hour,
|
||||
int? minute,
|
||||
int? second,
|
||||
int? millisecond,
|
||||
int? microsecond,
|
||||
]) =>
|
||||
DateTime(
|
||||
year,
|
||||
month ?? this.month,
|
||||
day ?? this.day,
|
||||
hour ?? this.hour,
|
||||
minute ?? this.minute,
|
||||
second ?? this.second,
|
||||
millisecond ?? this.millisecond,
|
||||
microsecond ?? this.microsecond,
|
||||
);
|
||||
|
||||
/// Change [month] of this date
|
||||
DateTime setMonth(
|
||||
int month, [
|
||||
int? day,
|
||||
int? hour,
|
||||
int? minute,
|
||||
int? second,
|
||||
int? millisecond,
|
||||
int? microsecond,
|
||||
]) =>
|
||||
DateTime(
|
||||
year,
|
||||
month,
|
||||
day ?? this.day,
|
||||
hour ?? this.hour,
|
||||
minute ?? this.minute,
|
||||
second ?? this.second,
|
||||
millisecond ?? this.millisecond,
|
||||
microsecond ?? this.microsecond,
|
||||
);
|
||||
|
||||
/// Change [day] of this date
|
||||
DateTime setDay(
|
||||
int day, [
|
||||
int? hour,
|
||||
int? minute,
|
||||
int? second,
|
||||
int? millisecond,
|
||||
int? microsecond,
|
||||
]) =>
|
||||
DateTime(
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour ?? this.hour,
|
||||
minute ?? this.minute,
|
||||
second ?? this.second,
|
||||
millisecond ?? this.millisecond,
|
||||
microsecond ?? this.microsecond,
|
||||
);
|
||||
|
||||
/// Change [hour] of this date
|
||||
DateTime setHour(
|
||||
int hour, [
|
||||
int? minute,
|
||||
int? second,
|
||||
int? millisecond,
|
||||
int? microsecond,
|
||||
]) =>
|
||||
DateTime(
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute ?? this.minute,
|
||||
second ?? this.second,
|
||||
millisecond ?? this.millisecond,
|
||||
microsecond ?? this.microsecond,
|
||||
);
|
||||
|
||||
/// Change [minute] of this date
|
||||
DateTime setMinute(
|
||||
int minute, [
|
||||
int? second,
|
||||
int? millisecond,
|
||||
int? microsecond,
|
||||
]) =>
|
||||
DateTime(
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute,
|
||||
second ?? this.second,
|
||||
millisecond ?? this.millisecond,
|
||||
microsecond ?? this.microsecond,
|
||||
);
|
||||
|
||||
/// Change [second] of this date
|
||||
DateTime setSecond(
|
||||
int second, [
|
||||
int? millisecond,
|
||||
int? microsecond,
|
||||
]) =>
|
||||
DateTime(
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute,
|
||||
second,
|
||||
millisecond ?? this.millisecond,
|
||||
microsecond ?? this.microsecond,
|
||||
);
|
||||
|
||||
/// Change [millisecond] of this date
|
||||
DateTime setMillisecond(
|
||||
int millisecond, [
|
||||
int? microsecond,
|
||||
]) =>
|
||||
DateTime(
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute,
|
||||
second,
|
||||
millisecond,
|
||||
microsecond ?? this.microsecond,
|
||||
);
|
||||
|
||||
/// Change [microsecond] of this date
|
||||
DateTime setMicrosecond(
|
||||
int microsecond,
|
||||
) =>
|
||||
DateTime(
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute,
|
||||
second,
|
||||
millisecond,
|
||||
microsecond,
|
||||
);
|
||||
|
||||
String format(List<String> formats) {
|
||||
String digits(int value, int length) {
|
||||
String ret = '$value';
|
||||
if (ret.length < length) {
|
||||
ret = '0' * (length - ret.length) + ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dayInYear(DateTime date) => date.difference(DateTime(date.year)).inDays;
|
||||
|
||||
final sb = StringBuffer();
|
||||
|
||||
for (String format in formats) {
|
||||
if (format.startsWith(escape)) {
|
||||
format = format.substring(1);
|
||||
sb.write(format);
|
||||
} else if (format == yyyy) {
|
||||
sb.write(digits(year, 4));
|
||||
} else if (format == yy) {
|
||||
sb.write(digits(year % 100, 2));
|
||||
} else if (format == mm) {
|
||||
sb.write(digits(month, 2));
|
||||
} else if (format == m) {
|
||||
sb.write(month);
|
||||
} else if (format == dd) {
|
||||
sb.write(digits(day, 2));
|
||||
} else if (format == d) {
|
||||
sb.write(day);
|
||||
} else if (format == w) {
|
||||
sb.write((day + 7) ~/ 7);
|
||||
} else if (format == W) {
|
||||
sb.write((dayInYear(this) + 7) ~/ 7);
|
||||
} else if (format == WW) {
|
||||
sb.write(digits((dayInYear(this) + 7) ~/ 7, 2));
|
||||
} else if (format == HH) {
|
||||
sb.write(digits(hour, 2));
|
||||
} else if (format == H) {
|
||||
sb.write(hour);
|
||||
} else if (format == hh) {
|
||||
int h = hour % 12;
|
||||
if (h == 0) {
|
||||
h = 12;
|
||||
}
|
||||
sb.write(digits(h, 2));
|
||||
} else if (format == h) {
|
||||
int h = hour % 12;
|
||||
if (h == 0) {
|
||||
h = 12;
|
||||
}
|
||||
sb.write(h);
|
||||
} else if (format == nn) {
|
||||
sb.write(digits(minute, 2));
|
||||
} else if (format == n) {
|
||||
sb.write(minute);
|
||||
} else if (format == ss) {
|
||||
sb.write(digits(second, 2));
|
||||
} else if (format == s) {
|
||||
sb.write(second);
|
||||
} else if (format == SSS) {
|
||||
sb.write(digits(millisecond, 3));
|
||||
} else if (format == S) {
|
||||
sb.write(millisecond);
|
||||
} else if (format == uuu) {
|
||||
sb.write(digits(microsecond, 3));
|
||||
} else if (format == u) {
|
||||
sb.write(microsecond);
|
||||
} else if (format == z) {
|
||||
if (timeZoneOffset.inMinutes == 0) {
|
||||
sb.write('Z');
|
||||
} else {
|
||||
if (timeZoneOffset.isNegative) {
|
||||
sb
|
||||
..write('-')
|
||||
..write(digits((-timeZoneOffset.inHours) % 24, 2))
|
||||
..write(digits((-timeZoneOffset.inMinutes) % 60, 2));
|
||||
} else {
|
||||
sb
|
||||
..write('+')
|
||||
..write(digits(timeZoneOffset.inHours % 24, 2))
|
||||
..write(digits(timeZoneOffset.inMinutes % 60, 2));
|
||||
}
|
||||
}
|
||||
} else if (format == Z) {
|
||||
sb.write(timeZoneName);
|
||||
} else {
|
||||
sb.write(format);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
bool operator <(DateTime other) => isBefore(other);
|
||||
|
||||
bool operator <=(DateTime other) =>
|
||||
isBefore(other) || isAtSameMomentAs(other);
|
||||
|
||||
bool operator >(DateTime other) => isAfter(other);
|
||||
|
||||
bool operator >=(DateTime other) => isAfter(other) || isAtSameMomentAs(other);
|
||||
}
|
22
packages/wyatt_type_utils/lib/src/extensions/encoding.dart
Normal file
22
packages/wyatt_type_utils/lib/src/extensions/encoding.dart
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
enum Encoding {
|
||||
utf8,
|
||||
utf16,
|
||||
base64,
|
||||
base16,
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:wyatt_type_utils/src/extensions/encoding.dart';
|
||||
|
||||
extension IterableExtension<T> on Iterable<T?>? {
|
||||
/// Returns true if this nullable iterable is either null or empty.
|
||||
bool get isNullOrEmpty => this == null || this!.isEmpty;
|
||||
|
||||
/// Returns false if this nullable iterable is either null or empty.
|
||||
bool get isNotNullOrEmpty => this != null && this!.isNotEmpty;
|
||||
}
|
||||
|
||||
extension IterableIntExtension on Iterable<int>? {
|
||||
/// Converts an [Iterable] of [int] to a [Uint8List].
|
||||
Uint8List toTypedList() => Uint8List.fromList(this?.toList() ?? []);
|
||||
|
||||
/// Converts a [Uint8List] to a [String] using the specified [Encoding].
|
||||
String toStr({final Encoding to = Encoding.utf16}) {
|
||||
String str;
|
||||
switch (to) {
|
||||
case Encoding.utf8:
|
||||
str = utf8.decode(this?.toList() ?? []);
|
||||
break;
|
||||
case Encoding.utf16:
|
||||
str = String.fromCharCodes(this ?? []);
|
||||
break;
|
||||
case Encoding.base64:
|
||||
str = base64.encode(this?.toList() ?? []);
|
||||
break;
|
||||
case Encoding.base16:
|
||||
str = List.generate(
|
||||
(this ?? []).length,
|
||||
(i) => (this ?? []).elementAt(i).toRadixString(16).padLeft(2, '0'),
|
||||
).join();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'dart:developer' as developer;
|
||||
|
||||
extension ObjectExtension<O extends Object> on O? {
|
||||
/// Returns true if the object is null.
|
||||
bool get isNull => this == null;
|
||||
|
||||
/// Returns true if the object is not null.
|
||||
bool get isNotNull => this != null;
|
||||
|
||||
/// Prints the object to the console.
|
||||
void log() => developer.log(toString());
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:wyatt_type_utils/src/extensions/encoding.dart';
|
||||
import 'package:wyatt_type_utils/src/extensions/iterable_extension.dart';
|
||||
|
||||
extension StringExtension on String? {
|
||||
/// Returns true if this string is either null or empty.
|
||||
bool get isNullOrEmpty => this == null || this!.isEmpty;
|
||||
|
||||
/// Returns false if this string is either null or empty.
|
||||
bool get isNotNullOrEmpty => this != null && this!.isNotEmpty;
|
||||
|
||||
/// Converts a [String] to a [Uint8List] using the specified [Encoding].
|
||||
Uint8List toBytes({final Encoding from = Encoding.utf16}) {
|
||||
Uint8List bytes;
|
||||
switch (from) {
|
||||
case Encoding.utf8:
|
||||
bytes = utf8.encode(this ?? '').toTypedList();
|
||||
break;
|
||||
case Encoding.utf16:
|
||||
bytes = (this ?? '').runes.toList().toTypedList();
|
||||
break;
|
||||
case Encoding.base64:
|
||||
bytes = base64.decode(this ?? '');
|
||||
break;
|
||||
case Encoding.base16:
|
||||
assert(
|
||||
(this ?? '').length.isEven,
|
||||
'String needs to be an even length.',
|
||||
);
|
||||
bytes = List.generate(
|
||||
(this ?? '').length ~/ 2,
|
||||
(i) =>
|
||||
int.parse((this ?? '').substring(i * 2, (i * 2) + 2), radix: 16),
|
||||
).toList().toTypedList();
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
@ -14,4 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'either_base.dart';
|
||||
export 'either/either_base.dart';
|
||||
export 'extensions/date_time_extension.dart';
|
||||
export 'extensions/encoding.dart';
|
||||
export 'extensions/iterable_extension.dart';
|
||||
export 'extensions/object_extension.dart';
|
||||
export 'extensions/string_extension.dart';
|
||||
export 'pair/pair.dart';
|
||||
|
116
packages/wyatt_type_utils/test/extensions_test.dart
Normal file
116
packages/wyatt_type_utils/test/extensions_test.dart
Normal file
@ -0,0 +1,116 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
void main() {
|
||||
group('ObjectExtension ', () {
|
||||
test('isNull returns true on null object', () {
|
||||
const int? myObject = null;
|
||||
expect(myObject.isNull, true);
|
||||
});
|
||||
test('isNull returns false on non-null object', () {
|
||||
// ignore: unnecessary_nullable_for_final_variable_declarations
|
||||
const int? myObject = 123;
|
||||
expect(myObject.isNull, false);
|
||||
});
|
||||
test('isNotNull returns false on null object', () {
|
||||
const int? myObject = null;
|
||||
expect(myObject.isNotNull, false);
|
||||
});
|
||||
test('isNotNull returns true on non-null object', () {
|
||||
// ignore: unnecessary_nullable_for_final_variable_declarations
|
||||
const int? myObject = 123;
|
||||
expect(myObject.isNotNull, true);
|
||||
});
|
||||
});
|
||||
|
||||
group('IterableExtension ', () {
|
||||
test('isNullOrEmpty returns true on null List', () {
|
||||
const List<int>? myIterable = null;
|
||||
expect(myIterable.isNullOrEmpty, true);
|
||||
});
|
||||
test('isNullOrEmpty returns true on empty List', () {
|
||||
const List<int> myIterable = [];
|
||||
expect(myIterable.isNullOrEmpty, true);
|
||||
});
|
||||
test('isNotNullOrEmpty returns false on null List', () {
|
||||
const List<int>? myIterable = null;
|
||||
expect(myIterable.isNotNullOrEmpty, false);
|
||||
});
|
||||
test('isNotNullOrEmpty returns true on empty List', () {
|
||||
const List<int> myIterable = [];
|
||||
expect(myIterable.isNotNullOrEmpty, false);
|
||||
});
|
||||
});
|
||||
|
||||
group('IterableIntExtension ', () {
|
||||
test('toTypedList() returns right Uint8List on [1, 2]', () {
|
||||
const List<int> myIterable = [1, 2];
|
||||
expect(myIterable.toTypedList(), Uint8List.fromList([1, 2]));
|
||||
});
|
||||
test('toTypedList() returns empty Uint8List on []', () {
|
||||
const List<int> myIterable = [];
|
||||
expect(myIterable.toTypedList(), Uint8List(0));
|
||||
});
|
||||
test('toStr() returns "abc" on [97,98,99]', () {
|
||||
const List<int> myIterable = [97, 98, 99];
|
||||
expect(myIterable.toStr(), 'abc');
|
||||
});
|
||||
|
||||
test('toStr() returns empty String on []', () {
|
||||
const List<int> myIterable = [];
|
||||
expect(myIterable.toStr(), '');
|
||||
});
|
||||
});
|
||||
|
||||
group('StringExtension ', () {
|
||||
test('isNullOrEmpty returns true on null String', () {
|
||||
const String? myString = null;
|
||||
expect(myString.isNullOrEmpty, true);
|
||||
});
|
||||
test('isNullOrEmpty returns true on empty String', () {
|
||||
const String myString = '';
|
||||
expect(myString.isNullOrEmpty, true);
|
||||
});
|
||||
test('isNotNullOrEmpty returns false on null String', () {
|
||||
const String? myString = null;
|
||||
expect(myString.isNotNullOrEmpty, false);
|
||||
});
|
||||
test('isNotNullOrEmpty returns true on empty String', () {
|
||||
const String myString = '';
|
||||
expect(myString.isNotNullOrEmpty, false);
|
||||
});
|
||||
test('toBytes() returns right Uint8List on "abc"', () {
|
||||
const String myString = 'abc';
|
||||
expect(myString.toBytes(), Uint8List.fromList([97, 98, 99]));
|
||||
});
|
||||
test('toBytes() returns empty Uint8List on empty String', () {
|
||||
const String myString = '';
|
||||
expect(myString.toBytes(), Uint8List(0));
|
||||
});
|
||||
});
|
||||
|
||||
group('DateTimeExtension ', () {
|
||||
test('format() with [dd, mm, yy] works', () {
|
||||
final DateTime date = DateTime(1999, 6, 30);
|
||||
expect(date.format([dd, '/', mm, '/', yy]), '30/06/99');
|
||||
});
|
||||
});
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user