Skip to content

Commit

Permalink
Fix docs + deprecate a few methods + add callWhen + small refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
ashtanko committed Jun 16, 2024
1 parent 9c935d8 commit bf4f411
Show file tree
Hide file tree
Showing 9 changed files with 382 additions and 306 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 0.1.5
- Fix code documentation.
- Deprecate `notEmpty`, `executeIf`, 'unwrapped' methods.
- Add new extension `callWhen` on nullable objects.
- Make examples more readable.

## 0.1.4
- Fix code documentation.
- Add LetX extension functions.
Expand Down
4 changes: 0 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,3 @@ publish:
# Generate test coverage report using the coverage package
coverage:
dart pub global run coverage:test_with_coverage

# Tag the release version in git
tag:
git tag -a v$(version) -m "Release version $(version)" && git push origin v$(version)
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,25 @@ void main() {
```dart
import 'package:nullx/nullx.dart';
void main() {
const int userAge = 20;
// Unwraps the nullable string and performs an operation on it
callWhen(
condition: () => userAge >= 18,
onMet: () {
// prints 'You are an adult.'
},
onNotMet: () {
// prints 'You are not an adult.'
},
);
}
```

```dart
import 'package:nullx/nullx.dart';
void main() {
const int? nullableInt = null;
nullableInt.orZero; // Outputs: 0
Expand Down
211 changes: 154 additions & 57 deletions example/nullx_example.dart
Original file line number Diff line number Diff line change
@@ -1,45 +1,54 @@
import 'package:nullx/nullx.dart';

void main() {
/// Variables
///
///
// ignore: unnecessary_nullable_for_final_variable_declarations
const int? nullableInt = 10;
nullableInt.let((item) => item * 2);
// print(result); // prints: 2

final list = [1, null, 3, null];
list.mapNonNull((item) => item * 2); // prints: [2, 6]
const nonNullInt = 1;
const int? nullInt = null;
// ignore: unnecessary_nullable_for_final_variable_declarations
const String? nullableString = 'example';
const String emptyString = '';
const String? nullString = null;
const double? nullDouble = null;
const bool? nullBool = null;

final list2 = [1, null, 3, null];
list2.mapNonNullIndexed((item, index) => item * index); // prints: [0, 6]
// ignore: unnecessary_nullable_for_final_variable_declarations
final List<int?>? nullableIntList = [1, null, 3, null];
// ignore: unnecessary_nullable_for_final_variable_declarations
final List<String?>? nullableStringList = [null, 'one', null, 'two', null];
// ignore: unnecessary_nullable_for_final_variable_declarations
const List<String?>? nullStringList = null;

// ignore: unnecessary_nullable_for_final_variable_declarations
List<int>? nullableList = [1, 2, 3];
nullableList.whatIfNotNullOrEmpty(
(list) => list,
() => 'List is null or empty', // whatIfNot
);
// prints: [1, 2, 3]
const List<String?>? emptyStringList = [];

nullableList.isNullOrEmpty; // prints: false
/// Collections
///
///
nullableList = null;
nullableList.isNullOrEmpty; // prints: true
// Maps over the list, applying a function to each non-null element,
nullableIntList?.mapNonNull((item) => item * 2); // prints: [2, 6]

nullableList = [];
nullableList.isNullOrEmpty; // prints: true
// Maps over the list, applying a function to each non-null element and its
// index
// prints: [0, 6]
nullableIntList?.mapNonNullIndexed((item, index) => item * index);

// ignore: unnecessary_nullable_for_final_variable_declarations
const String? nullableString = 'example';

// Unwraps the nullable string and performs an operation on it
unwrapped(nullableString, (value) {}); // prints: 'example'
nullableIntList.whatIfNotNullOrEmpty(
(list) => list,
() => 'List is null or empty', // whatIfNot
);
// prints: [1, 2, 3]

// A list of nullable strings
final List<String?> strings = [null, 'one', null, 'two', null];
nullableIntList.isNullOrEmpty; // prints: false

// Maps over the list, applying a function to each non-null element,
// then filters out null results and converts the result to a list
strings.map((s) => s.letNonNull((s) => s.length)).whereType<int>().toList();
nullStringList.isNullOrEmpty; // prints: true
emptyStringList.isNullOrEmpty; // prints: true
nullableStringList.isNullOrEmpty; // prints: false

// A list of nullable strings
final List<String?> strs = [null, 'one', null, 'two', null];
Expand All @@ -53,53 +62,141 @@ void main() {
// A dynamic constant
const dynamic value = 'Hello';

// Tries to cast the dynamic value to a String
final String? name = tryCast<String>(value);

// Tries to cast the dynamic value to an int
final int? age = tryCast<int>(value);
const int userAge = 20;
// prints: 'You are an adult.'

// Performs an operation on the name if it's not null
name.let((n) => n);
const double? nullableDouble = null;
nullableDouble.orZero; // Outputs: 0.0
nullableDouble.or(defaultValue: 5.5); // Outputs: 5.5

// Performs an operation on the age if it's not null
age.let((a) => a);
const bool? nullableBool = null;
nullableBool.orFalse; // Outputs: false
nullableBool.or(defaultValue: true); // Outputs: true

nullableInt.letNonNull((value) => value * 2); // prints: 2
/// Types
///
///
const int userAge = 20;
executeIf(
() => userAge >= 18,
onConditionMet: () {
// Unwraps the nullable string and performs an operation on it
callWhen(
condition: () => userAge >= 18,
onMet: () {
// prints 'You are an adult.'
},
onConditionNotMet: () {
onNotMet: () {
// prints 'You are not an adult.'
},
);

executeIfAs<String>(
// Unwraps the nullable string and performs an operation on it
final res1 = executeIfAs<String>(
() => userAge >= 18,
ifTrue: () => 'You are an adult.',
ifFalse: () => 'You are not an adult.',
);
// prints: 'You are an adult.'

// ignore: avoid_print
notEmpty(nullableString, (s) => print(s)); // prints: 'The value is: example'
print(res1); // prints: 'You are an adult.'

const int? nullableInt2 = null;
nullableInt2.orZero; // Outputs: 0
nullableInt2.or(defaultValue: 5); // Outputs: 5
// Unwraps the nullable string and performs an operation on it
nullableString.unwrapped((value) {}); // prints: 'example'

const double? nullableDouble = null;
nullableDouble.orZero; // Outputs: 0.0
nullableDouble.or(defaultValue: 5.5); // Outputs: 5.5
// Unwraps the nullable string and performs an operation on it
// ignore: avoid_print
nullableString.notEmpty((s) => print(s)); // prints: 'The value is: example'

const bool? nullableBool = null;
nullableBool.orFalse; // Outputs: false
nullableBool.or(defaultValue: true); // Outputs: true
// Unwraps the nullable string and performs an operation on it
final result = nullableInt.conditionNotNullWith<int>(
isTrue: (item) => item * 2,
isFalse: () => 0,
);
// ignore: avoid_print
print(result); // prints: 20

final res2 = nullableInt.conditionNotNullAs<int>(
condition: (value) => value > 5,
isTrue: (value) => value * 2,
isFalse: () => -1,
);

// ignore: avoid_print
print(res2); // prints: 20

// Unwraps the nullable string and performs an operation on it
const num = 10;
final res3 = num.takeIf((value) => value > 5);
// ignore: avoid_print
print('takeIf: $res3'); // prints: 10

final res4 = num.takeUnless((value) => value > 5);
// ignore: avoid_print
print('takeUnless: $res4'); // prints: 10

// Unwraps the nullable string and performs an operation on it
final res5 = nullableInt.let((item) => item * 2);
// ignore: avoid_print
print('let: $res5'); // prints: 20

// Unwraps the nullable string and performs an operation on it
final res6 = nonNullInt.run((item) => item * 2);
// ignore: avoid_print
print('run: $res6'); // prints: 2

var str = 'Hello';
str.also((item) => str = item.toUpperCase());
// ignore: avoid_print
print('also: $str'); // prints: HELLO

// Maps over the list, applying a function to each non-null element,
// then filters out null results and converts the result to a list
nullableStringList
?.map((s) => s.letNonNull((s) => s.length))
.whereType<int>()
.toList();

// ignore: avoid_print
print('call isNullOrEmpty on null string: ${nullableString.isNullOrEmpty}');

// ignore: avoid_print
print('call isNullOrEmpty on empty string: ${emptyString.isNullOrEmpty}');

final res8 = nullString.orDefault('hi');
// ignore: avoid_print
print('orDefault: $res8'); // prints: 'hi'

// Unwraps the nullable int
nullInt.orZero; // Outputs: 0
nullInt.or(defaultValue: 5); // Outputs: 5

// Unwraps the nullable double
nullDouble.orZero; // Outputs: 0.0
nullDouble.or(defaultValue: 5.5); // Outputs: 5.5

// Unwraps the nullable bool
nullBool.orFalse; // Outputs: false
nullBool.or(defaultValue: true); // Outputs: true

/// Utils
///
///
// Tries to cast the dynamic value to a String
final String? name = tryCast<String>(value);

// Tries to cast the dynamic value to an int
final int? age = tryCast<int>(value);

// Performs an operation on the name if it's not null
name.let((n) => n);

// Performs an operation on the age if it's not null
age.let((a) => a);

// A placeholder for future code
todo();
// Throws a [NotImplementedError] indicating that an operation is
try {
todo();
} catch (e) {
// ignore: avoid_print
print(e); // prints: An operation is not implemented.
}
}
42 changes: 23 additions & 19 deletions lib/src/collections.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,30 @@ extension NullableMapExtension<T, R> on Iterable<T?> {
}
}

/// Extension on `List<T>?` to add a `whatIfNotNullOrEmpty` method.
///
/// This extension provides a convenient way to handle nullable lists.
/// The `whatIfNotNullOrEmpty` method takes two functions: `whatIf` and
/// `whatIfNot`.
///
/// If the list is not null and not empty, it applies the `whatIf` function
/// to the list. If the list is null or empty, it calls the `whatIfNot` function.
///
/// Example usage:
///
/// ```dart
/// List<int>? nullableList = [1, 2, 3];
/// nullableList.whatIfNotNullOrEmpty(
/// (list) => print(list), // whatIf
/// () => print('List is null or empty'), // whatIfNot
/// );
/// // prints: [1, 2, 3]
/// ```
/// Extension on `List<T>?`.
extension WhatIfNotNullOrEmptyExtension<T> on List<T>? {
/// Executes the [whatIf] function if the list is not null and not empty,
/// otherwise executes the [whatIfNot] function.
///
/// This function is useful when you need to perform an operation on a list
/// that could be null or empty.
///
/// The [whatIf] function should accept a single argument of type `List<T>`,
/// which represents the non-null and non-empty list.
///
/// The [whatIfNot] function should be a function that takes no arguments
/// and is called when the list is null or empty.
///
/// Example usage:
///
/// ```dart
/// List<int>? nullableList = [1, 2, 3];
/// nullableList.whatIfNotNullOrEmpty(
/// (list) => print(list), // whatIf
/// () => print('List is null or empty'), // whatIfNot
/// );
/// // prints: [1, 2, 3]
/// ```
void whatIfNotNullOrEmpty(
void Function(List<T>) whatIf,
void Function() whatIfNot,
Expand Down
Loading

0 comments on commit bf4f411

Please sign in to comment.