Update README.md

This commit is contained in:
2025-05-16 14:58:50 +02:00
parent f4b5c252d7
commit a3b2dc5c26
+129 -119
View File
@@ -7,25 +7,17 @@ providing utility functions and extensions that simplify common tasks.
## Features ## Features
- **Ticker Utility**: A utility class that facilitates time-based actions, - **Ticker Utility**: A utility class that facilitates time-based actions, perfect for animations or any timing-related operations.
perfect for animations or any timing-related operations. - **JSON Converter**: Simplifies the process of converting JSON data into Dart objects.
- **JSON Converter**: Simplifies the process of converting JSON data into - **DateTime Extensions**: Adds additional functionality to the `DateTime` class, making it easier to format dates and calculate differences.
Dart objects. - **String Extensions**: Enhances the `String` class by adding new methods for common transformations and checks.
- **DateTime Extensions**: Adds additional functionality to the `DateTime` - **JWT Utilities**: Provides getters to parse a JWT token from a `String`, then get common properties from it.
class, making it easier to format dates and calculate differences. - **List Extensions**: Adds a new `unique` operator for filtering `List` items, as well as getters for `isNullOrEmpty`, `isEmptyOrNull`, `isNotNullOrEmpty`, and `isNotEmptyOrNull`. Furthermore, an `equals` extension has been introduced which can be used to compare two lists.
- **String Extensions**: Enhances the `String` class by adding new methods for - **FixedSizeList**: Provides a list of a predictable size, which drops the first value when additional values are added which would otherwise cause the list to exceed its capacity.
common transformations and checks.
- **JWT Utilities**: Provides getters to parse a JWT token from a `String`, then
get common properties from it.
- **List Extensions**: Adds a new `unique` operator for filtering `List` items,
as well as getters for `isNullOrEmpty`, `isEmptyOrNull`, `isNotNullOrEmpty`,
and `isNotEmptyOrNull`. Furthermore, an `equals` extension has been introduced
which can be used to compare two lists.
## Getting Started ## Getting Started
To use this package in your Dart project, add it to your project's To use this package in your Dart project, add it to your project's `pubspec.yaml` file:
`pubspec.yaml` file:
```yaml ```yaml
dependencies: dependencies:
@@ -40,50 +32,45 @@ import 'package:arcane_helper_utils/arcane_helper_utils.dart';
## Usage Examples ## Usage Examples
Here are some examples of how to use the utilities and extensions provided by Here are some examples of how to use the utilities and extensions provided by this package:
this package:
### Ticker ### Ticker
The `Ticker` can be used as a countdown or interval timer. The `Ticker` can be used as a countdown or interval timer.
```dart ```dart
final Stream<int> ticker = const Ticker().tick( final Stream<int> ticker = const Ticker().tick(
timeout: Duration(seconds: 30), timeout: Duration(seconds: 30),
interval: Duration(seconds: 5) interval: Duration(seconds: 5)
); );
await for (final int ticksRemaining in ticker) { await for (final int ticksRemaining in ticker) {
if (ticksRemaining == 0) print("Time's up!"); if (ticksRemaining == 0) print("Time's up!");
print('Tick! $ticksRemaining'); print('Tick! $ticksRemaining');
} }
``` ```
### JSON Conversion ### JSON Conversion
These helper methods are used in conjunction with the Freezed package to These helper methods are used in conjunction with the Freezed package to annotate fields that need to be converted from one data type to another.
annotate fields that need to be converted from one data type to another. The available conversions are:
The available conversions are:
- `String?` to `int?` - `String?` to `int?`
- `String?` to `double?` - `String?` to `double?`
Provided the following JSON output, the `valueIsMaybeNull` field will be Provided the following JSON output, the `valueIsMaybeNull` field will be converted from an empty `String` to `null`, the `valueIsDouble` field will be converted from a `String?` to a `double?`, and the `valueIsInt` field will be converted from a `String?` to an `int?`:
converted from an empty `String` to `null`, the `valueIsDouble` field will
be converted from a `String?` to a `double?`, and the `valueIsInt` field will be
converted from a `String?` to an `int?`:
```json ```json
{ {
"valueIsMaybeNull": "", "valueIsMaybeNull": "",
"valueIsDouble": "123.456", "valueIsDouble": "123.456",
"valueIsInt": "123" "valueIsInt": "123"
} }
``` ```
```dart ```dart
@freezed @freezed
abstract class MyFreezedClass with _$MyFreezedClass { abstract class MyFreezedClass with _$MyFreezedClass {
const factory MyFreezedClass({ const factory MyFreezedClass({
@DecimalConverter() double? valueIsMaybeNull, @DecimalConverter() double? valueIsMaybeNull,
@DecimalConverter() double? valueIsDouble, @DecimalConverter() double? valueIsDouble,
@@ -94,28 +81,26 @@ abstract class MyFreezedClass with _$MyFreezedClass {
_$MyFreezedClassFromJson(json); _$MyFreezedClassFromJson(json);
const MyFreezedClass._(); const MyFreezedClass._();
} }
``` ```
### DateTime Extensions ### DateTime Extensions
These extensions add helpful methods to the `DateTime` class, making it easier These extensions add helpful methods to the `DateTime` class, making it easier to handle common date and time operations such as formatting, comparisons, and calculations.
to handle common date and time operations such as formatting, comparisons, and
calculations.
These are broken down into the following categories: These are broken down into the following categories:
- Start and end of period calculations - Start and end of period calculations
- Comparison operations - Comparison operations
- Period information operations - Period information operations
- "Yesterday" and "tomorrow" getters - "Yesterday" and "tomorrow" getters
- Leap year calculations
#### Start and End of Period Calculations #### Start and End of Period Calculations
The following operations are now available on a `DateTime` object: The following operations are now available on a `DateTime` object:
- `startOfHour`: Returns a new `DateTime` object where the time stamp is set to - `startOfHour`: Returns a new `DateTime` object where the time stamp is set to the beginning of the given hour.
the beginning of the given hour.
```dart ```dart
final DateTime dateTime = DateTime(2019, 1, 1, 13, 45); final DateTime dateTime = DateTime(2019, 1, 1, 13, 45);
@@ -123,8 +108,7 @@ The following operations are now available on a `DateTime` object:
print(dateTime.startOfHour); // 2019-01-01T13:00:00.0 print(dateTime.startOfHour); // 2019-01-01T13:00:00.0
``` ```
- `endOfHour`: Returns a new `DateTime` object where the time stamp is set to - `endOfHour`: Returns a new `DateTime` object where the time stamp is set to the end of the given hour.
the end of the given hour.
```dart ```dart
final DateTime dateTime = DateTime(2019, 1, 1, 13, 45); final DateTime dateTime = DateTime(2019, 1, 1, 13, 45);
@@ -132,8 +116,7 @@ The following operations are now available on a `DateTime` object:
print(dateTime.endOfHour); // 2019-01-01T13:59:59.999 print(dateTime.endOfHour); // 2019-01-01T13:59:59.999
``` ```
- `startOfDay`: Returns a new `DateTime` object where the time stamp is set to - `startOfDay`: Returns a new `DateTime` object where the time stamp is set to the beginning of the day.
the beginning of the day.
```dart ```dart
final DateTime dateTime = DateTime(2019, 1, 1, 13, 45); final DateTime dateTime = DateTime(2019, 1, 1, 13, 45);
@@ -141,8 +124,7 @@ The following operations are now available on a `DateTime` object:
print(dateTime.startOfDay); // 2019-01-01T00:00:00.0 print(dateTime.startOfDay); // 2019-01-01T00:00:00.0
``` ```
- `endOfDay`: Returns a new `DateTime` object where the time stamp is set to the - `endOfDay`: Returns a new `DateTime` object where the time stamp is set to the end of the day.
end of the day.
```dart ```dart
final DateTime dateTime = DateTime(2019, 1, 1, 13, 45); final DateTime dateTime = DateTime(2019, 1, 1, 13, 45);
@@ -150,8 +132,7 @@ The following operations are now available on a `DateTime` object:
print(dateTime.endOfDay); // 2019-01-01T23:59:59.9 print(dateTime.endOfDay); // 2019-01-01T23:59:59.9
``` ```
- `startOfWeek`: Returns a new `DateTime` object where the time stamp is set to - `startOfWeek`: Returns a new `DateTime` object where the time stamp is set to the beginning of the week (Monday).
the beginning of the week (Monday).
```dart ```dart
final DateTime dateTime = DateTime(2023, 9, 10); final DateTime dateTime = DateTime(2023, 9, 10);
@@ -159,8 +140,7 @@ The following operations are now available on a `DateTime` object:
print(dateTime.startOfWeek); // 2023-09-04 print(dateTime.startOfWeek); // 2023-09-04
``` ```
- `endOfWeek`: Returns a new `DateTime` object where the time stamp is set to - `endOfWeek`: Returns a new `DateTime` object where the time stamp is set to the end of the week (Sunday).
the end of the week (Sunday).
```dart ```dart
final DateTime dateTime = DateTime(2023, 9, 10); final DateTime dateTime = DateTime(2023, 9, 10);
@@ -168,8 +148,7 @@ The following operations are now available on a `DateTime` object:
print(dateTime.endOfWeek); // 2023-09-17T23:59:59.999999 print(dateTime.endOfWeek); // 2023-09-17T23:59:59.999999
``` ```
- `startOfMonth`: Returns a new `DateTime` object where the time stamp is set to - `startOfMonth`: Returns a new `DateTime` object where the time stamp is set to the beginning of the month.
the beginning of the month.
```dart ```dart
final DateTime dateTime = DateTime(2023, 9, 10); final DateTime dateTime = DateTime(2023, 9, 10);
@@ -177,8 +156,7 @@ The following operations are now available on a `DateTime` object:
print(dateTime.startOfMonth); // 2023-09-01T00:00:00.0 print(dateTime.startOfMonth); // 2023-09-01T00:00:00.0
``` ```
- `endOfMonth`: Returns a new `DateTime` object where the time stamp is set to - `endOfMonth`: Returns a new `DateTime` object where the time stamp is set to the end of the month.
the end of the month.
```dart ```dart
final DateTime dateTime = DateTime(2023, 9, 10); final DateTime dateTime = DateTime(2023, 9, 10);
@@ -186,8 +164,7 @@ The following operations are now available on a `DateTime` object:
print(dateTime.endOfMonth); // 2023-09-30T23:59:59.999999 print(dateTime.endOfMonth); // 2023-09-30T23:59:59.999999
``` ```
- `startOfYear`: Returns a new `DateTime` object where the time stamp is set to - `startOfYear`: Returns a new `DateTime` object where the time stamp is set to the beginning of the year.
the beginning of the year.
```dart ```dart
final DateTime dateTime = DateTime(2023, 9, 10); final DateTime dateTime = DateTime(2023, 9, 10);
@@ -195,8 +172,7 @@ The following operations are now available on a `DateTime` object:
print(dateTime.startOfYear); // 2023-01-01T00:00:00.0 print(dateTime.startOfYear); // 2023-01-01T00:00:00.0
``` ```
- `endOfYear`: Returns a new `DateTime` object where the time stamp is set to - `endOfYear`: Returns a new `DateTime` object where the time stamp is set to the end of the year.
the end of the year.
```dart ```dart
final DateTime dateTime = DateTime(2023, 9, 10); final DateTime dateTime = DateTime(2023, 9, 10);
@@ -204,18 +180,16 @@ The following operations are now available on a `DateTime` object:
print(dateTime.endOfYear); // 2023-12-31T23:59:59.999999 print(dateTime.endOfYear); // 2023-12-31T23:59:59.999999
``` ```
#### Comparison Operations #### Comparison Operations
- `isToday`: Returns `true` if the provided `DateTime` is today, otherwise - `isToday`: Returns `true` if the provided `DateTime` is today, otherwise returns `false`.
returns `false`.
```dart ```dart
final DateTime today = DateTime(2024, 9, 10); final DateTime today = DateTime(2024, 9, 10);
final bool notToday = DateTime(2001, 12, 31).isToday; // false final bool notToday = DateTime(2001, 12, 31).isToday; // false
``` ```
- `isSameDayAs`: Compares two `DateTime` objects and returns `true` if they - `isSameDayAs`: Compares two `DateTime` objects and returns `true` if they represent the same day.
represent the same day.
```dart ```dart
final DateTime first = DateTime(2001, 1, 1); final DateTime first = DateTime(2001, 1, 1);
@@ -226,42 +200,40 @@ The following operations are now available on a `DateTime` object:
final bool firstAndThird = first.isSameDayAs(third); // true final bool firstAndThird = first.isSameDayAs(third); // true
``` ```
#### Period Information Operations #### Period Information Operations
- `daysInMonth`: Returns an `int` with the number of days in a provided month. - `daysInMonth`: Returns an `int` with the number of days in a provided month.
```dart ```dart
final int daysInMonth = DateTime(2024, 9).daysInMonth; // 30 final int daysInMonth = DateTime(2024, 9).daysInMonth; // 30
``` ```
- `firstDayOfWeek`: Returns a new `DateTime` object where the time stamp is set - `firstDayOfWeek`: Returns a new `DateTime` object where the time stamp is set to the beginning of the first day (Sunday) of the original `DateTime`'s week.
to the beginning of the first day (Sunday) of the original `DateTime`'s week.
```dart ```dart
final DateTime today = DateTime(2024, 9, 10); // Tuesday final DateTime today = DateTime(2024, 9, 10); // Tuesday
final DateTime sunday = today.firstDayOfWeek; // Sunday final DateTime sunday = today.firstDayOfWeek; // Sunday
``` ```
#### "Yesterday" and "tomorrow" getters #### "Yesterday" and "tomorrow" getters
- `yesterday`: returns a new `DateTime` object for the previous start of day. - `yesterday`: returns a new `DateTime` object for the previous start of day.
```dart ```dart
final DateTime now = DateTime.now(); // 2024-10-07 13:37:48.274 final DateTime now = DateTime.now(); // 2024-10-07 13:37:48.274
final DateTime yesterday = DateTime(0).yesterday; // 2024-10-06 00:00:00.000 final DateTime yesterday = DateTime(0).yesterday; // 2024-10-06 00:00:00.000
``` ```
- `tomorrow`: returns a new `DateTime` object for tomorrow's start of day. - `tomorrow`: returns a new `DateTime` object for tomorrow's start of day.
```dart ```dart
final DateTime now = DateTime.now(); // 2024-10-07 13:37:48.274 final DateTime now = DateTime.now(); // 2024-10-07 13:37:48.274
final DateTime tomorrow = DateTime(0).tomorrow; // 2024-10-08 00:00:00.000 final DateTime tomorrow = DateTime(0).tomorrow; // 2024-10-08 00:00:00.000
``` ```
#### Leap Years #### Leap Years
- `isLeapYear`: returns a `bool` corresponding to whether a given year is a leap - `isLeapYear`: returns a `bool` corresponding to whether a given year is a leap year. This can also be used directly on an `int`.
year. This can also be used directly on an `int`.
```dart ```dart
print(DateTime(2024).isLeapYear); // true print(DateTime(2024).isLeapYear); // true
@@ -272,26 +244,25 @@ The following operations are now available on a `DateTime` object:
### JWT Parsing ### JWT Parsing
These extensions enhance the `String` class with JWT-specific functionalities, These extensions enhance the `String` class with JWT-specific functionalities, making it easier to handle JSON Web Tokens directly as `String` objects.
making it easier to handle JSON Web Tokens directly as `String` objects.
Here are some examples of how these methods can be utilized: Here are some examples of how these methods can be utilized:
- Parse a JWT string - Parse a JWT string
```dart ```dart
String token = "your.jwt.token"; String token = "your.jwt.token";
final JwtPayload? payload = token.jwt; // Returns the JWT's payload final JwtPayload? payload = token.jwt; // Returns the JWT's payload
``` ```
- Extracting the email address (`jwt["sub"]`) - Extracting the email address (`jwt["sub"]`)
```dart ```dart
String jwt = "your.jwt.token"; String jwt = "your.jwt.token";
final String? email = jwt.jwt.email; // Returns the email address in the JWT final String? email = jwt.jwt.email; // Returns the email address in the JWT
``` ```
- Extracting the token expiration time (`jwt["exp"]`) - Extracting the token expiration time (`jwt["exp"]`)
```dart ```dart
String jwt = "your.jwt.token"; String jwt = "your.jwt.token";
@@ -299,21 +270,21 @@ Here are some examples of how these methods can be utilized:
final DateTime? email = jwt.jwt.expiryTime; final DateTime? email = jwt.jwt.expiryTime;
``` ```
- Extracting the user ID (`jwt["uid"]`) - Extracting the user ID (`jwt["uid"]`)
```dart ```dart
String jwt = "your.jwt.token"; String jwt = "your.jwt.token";
final String? uid = jwt.jwt.userId; // Returns the UID value from the token final String? uid = jwt.jwt.userId; // Returns the UID value from the token
``` ```
- Extracting the given name (`jwt["given_name"]`) - Extracting the given name (`jwt["given_name"]`)
```dart ```dart
String jwt = "your.jwt.token"; String jwt = "your.jwt.token";
final String? uid = jwt.jwt.givenName; // Returns the given name from the token final String? uid = jwt.jwt.givenName; // Returns the given name from the token
``` ```
- Extracting the family name (`jwt["family_name"]`) - Extracting the family name (`jwt["family_name"]`)
```dart ```dart
String jwt = "your.jwt.token"; String jwt = "your.jwt.token";
@@ -322,11 +293,9 @@ Here are some examples of how these methods can be utilized:
### String Utilities ### String Utilities
The following utilities have been added to enhance working with `String` The following utilities have been added to enhance working with `String` objects:
objects:
- `isNullOrEmpty`: Returns `true` if a `String?` is either null or consists of - `isNullOrEmpty`: Returns `true` if a `String?` is either null or consists of only whitespace.
only whitespace.
```dart ```dart
const String? nullString = null; const String? nullString = null;
@@ -338,8 +307,7 @@ objects:
print(nonEmptyString.isNullOrEmpty) // false print(nonEmptyString.isNullOrEmpty) // false
``` ```
- `isNotNullOrEmpty`: Returns `true` if a `String?` is neither null nor consists - `isNotNullOrEmpty`: Returns `true` if a `String?` is neither null nor consists of only whitespace.
of only whitespace.
```dart ```dart
const String? nullString = null; const String? nullString = null;
@@ -351,45 +319,41 @@ objects:
print(nonEmptyString.isNotNullOrEmpty) // true print(nonEmptyString.isNotNullOrEmpty) // true
``` ```
- `splitByLength(int length)`: Splits a `String` into a `List<String>` where - `splitByLength(int length)`: Splits a `String` into a `List<String>` where each value is of the maximum length provided.
each value is of the maximum length provided.
```dart ```dart
const String text = "DartLang"; const String text = "DartLang";
final List<String> result = text.splitByLength(3); // ["Dar", "tLa", "ng"] final List<String> result = text.splitByLength(3); // ["Dar", "tLa", "ng"]
``` ```
- `capitalize`: Capitalizes the first letter of a given `String` - `capitalize`: Capitalizes the first letter of a given `String`
```dart ```dart
const String text = "hello"; const String text = "hello";
final String capitalized = text.capitalize; // "Hello" final String capitalized = text.capitalize; // "Hello"
``` ```
- `capitalizeWords`: Capitalizes the first letter of each word in a given `String` - `capitalizeWords`: Capitalizes the first letter of each word in a given `String`
```dart ```dart
String text = "hello world"; String text = "hello world";
String capitalizedWords = text.capitalizeWords; // "Hello World" String capitalizedWords = text.capitalizeWords; // "Hello World"
``` ```
- `spacePascalCase`: Adds spaces between words in a PascalCase `String` - `spacePascalCase`: Adds spaces between words in a PascalCase `String`
```dart ```dart
String text = "ArcaneHelperUtils"; String text = "ArcaneHelperUtils";
String spaced = text.spacePascalCase; // "Arcane Helper Utils" String spaced = text.spacePascalCase; // "Arcane Helper Utils"
``` ```
Additionally, the `CommonString` class provides a quick shortcut to common Additionally, the `CommonString` class provides a quick shortcut to common strings, such as punctuation marks that are otherwise cumbersome to find or type.
strings, such as punctuation marks that are otherwise cumbersome to find or type.
### List Extensions ### List Extensions
The following extensions have been added to the `List` object: The following extensions have been added to the `List` object:
- `unique([Id Function(E element)? id, bool inplace = true])`: Filters a list - `unique([Id Function(E element)? id, bool inplace = true])`: Filters a list by a given element, returning only non-duplicate values. Can return either a new `List` or filter the existing list by specifying the `inplace` option.
by a given element, returning only non-duplicate values. Can return either a
new `List` or filter the existing list by specifying the `inplace` option.
```dart ```dart
const List<int> list = [1, 2, 2, 3, 4, 4]; const List<int> list = [1, 2, 2, 3, 4, 4];
@@ -404,7 +368,7 @@ The following extensions have been added to the `List` object:
print(uniquePeople.map((p) => p.name)); // Output: ['Alice', 'Bob'] print(uniquePeople.map((p) => p.name)); // Output: ['Alice', 'Bob']
``` ```
- `isNullOrEmpty`: Checks if a list is either null or empty. - `isNullOrEmpty`: Checks if a list is either null or empty.
```dart ```dart
const List<int> list = [1, 2, 3]; const List<int> list = [1, 2, 3];
@@ -415,7 +379,7 @@ The following extensions have been added to the `List` object:
print(nullList.isNullOrEmpty); // Output: true print(nullList.isNullOrEmpty); // Output: true
``` ```
- `isNullOrEmpty`: Checks if a list is either null or empty. - `isNullOrEmpty`: Checks if a list is either null or empty.
```dart ```dart
final List<int> list = [1, 2, 3]; final List<int> list = [1, 2, 3];
@@ -426,7 +390,7 @@ The following extensions have been added to the `List` object:
print(nullList.isNullOrEmpty); // Output: true print(nullList.isNullOrEmpty); // Output: true
``` ```
- `equals`: Compares two lists to see if they are equal. - `equals`: Compares two lists to see if they are equal.
```dart ```dart
List<int?>? list1 = [1, 2, null, 4]; List<int?>? list1 = [1, 2, null, 4];
@@ -461,7 +425,53 @@ The following extensions have been added to the `List` object:
print(list8.equals(list9, ignoreSorting: false)); print(list8.equals(list9, ignoreSorting: false));
``` ```
### Fixed size list
The `FixedSizeList` operates much like a traditional `List` with one exception: the length of the list is defined upon creation and adding new items to the list which would otherwise cause the length of the list to exceed the list's capacity will cause the first item(s) to be removed from the list.
Here's an example: Say you want to keep a list of the last 3 log messages. You can create a `FixedSizeList` to push these log messages into:
```dart
// Create a FixedSizeList with a capacity of 3 strings.
final recentLogs = FixedSizeList(3);
// Output: Initial recentLogs: []
print("Initial recentLogs: ${recentLogs.items}");
// Add some log messages.
recentLogs.add("Request received at 10:00 AM");
print("recentLogs after first add: ${recentLogs.items}");
// Output: recentLogs after first add: [Request received at 10:00 AM]
recentLogs.add("Processing request...");
print("recentLogs after second add: ${recentLogs.items}");
// Output: recentLogs after second add: [Request received at 10:00 AM, Processing request...]
recentLogs.add("Request completed at 10:05 AM");
print("recentLogs after third add: ${recentLogs.items}");
// Output: recentLogs after third add: [Request received at 10:00 AM, Processing request..., Request completed at 10:05 AM]
// Add one more log message, which will cause the oldest one to be removed.
recentLogs.add("Sending response...");
print("recentLogs after fourth add: ${recentLogs.items}");
// Output: recentLogs after fourth add: [Processing request..., Request completed at 10:05 AM, Sending response...]
```
A `FixedSizeList` can be created with a capacity then filled up later (as in the previous example), or a value can be passed in alongside the capacity. The value being passed in should not exceed the length of the given capacity.
```dart
final numbers = FixedSizeList.from([1, 2, 3]); // The list is set to a capacity of 3 (the length of the input)
final moreNumbers = FixedSizeList(3, value: [1, 2, 3]);
final throwsException = FixedSizeList(3, value: [1, 2, 3, 4]); // Throws an exception because [value] exceeds the given capacity.
```
Other `List` factories are supported when creating a `FixedSizeList`, including:
- `filled`
- `empty`
- `from`
- `of`
- `generate`
## Contributing ## Contributing
Contributions are welcome! Feel free to fork the repository and submit pull Contributions are welcome! Feel free to fork the repository and submit pull requests.
requests.