Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,17 +271,17 @@ class Person extends Equatable {
}
```

## EquatableMixin
## Mixin Usage

Sometimes it isn't possible to extend `Equatable` because your class already has a superclass.
In this case, you can still get the benefits of `Equatable` by using the `EquatableMixin`.
In this case, you can still get the benefits of `Equatable` by using `Equatable` as a `mixin`.

### Usage

Let's say we want to make an `EquatableDateTime` class, we can use `EquatableMixin` like so:
Let's say we want to make an `EquatableDateTime` class, we can use `Equatable` like so:

```dart
class EquatableDateTime extends DateTime with EquatableMixin {
class EquatableDateTime extends DateTime with Equatable {
EquatableDateTime(
int year, [
int month = 1,
Expand Down
28 changes: 25 additions & 3 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ linter:
- always_put_required_named_parameters_first
- always_use_package_imports
- annotate_overrides
- annotate_redeclares
- avoid_bool_literals_in_conditional_expressions
- avoid_catching_errors
- avoid_double_and_int_checks
Expand All @@ -29,7 +30,6 @@ linter:
- avoid_init_to_null
- avoid_js_rounded_ints
- avoid_multiple_declarations_per_line
- avoid_null_checks_in_equality_operators
- avoid_positional_boolean_parameters
- avoid_print
- avoid_private_typedef_functions
Expand Down Expand Up @@ -65,7 +65,9 @@ linter:
- dangling_library_doc_comments
- depend_on_referenced_packages
- deprecated_consistency
- deprecated_member_use_from_same_package
- directives_ordering
- do_not_use_environment
- empty_catches
- empty_constructor_bodies
- empty_statements
Expand All @@ -86,23 +88,28 @@ linter:
- library_private_types_in_public_api
- lines_longer_than_80_chars
- literal_only_boolean_expressions
- matching_super_parameters
- missing_code_block_language_in_doc_comment
- missing_whitespace_between_adjacent_strings
- no_adjacent_strings_in_list
- no_default_cases
- no_duplicate_case_values
- no_leading_underscores_for_library_prefixes
- no_leading_underscores_for_local_identifiers
- no_literal_bool_comparisons
- no_logic_in_create_state
- no_runtimeType_toString
- no_self_assignments
- no_wildcard_variable_uses
- non_constant_identifier_names
- noop_primitive_operations
- null_check_on_nullable_type_parameter
- null_closures
- omit_local_variable_types
- omit_obvious_local_variable_types
- one_member_abstracts
- only_throw_errors
- overridden_fields
- package_api_docs
- package_names
- package_prefixed_library_names
- prefer_adjacent_string_concatenation
Expand All @@ -120,6 +127,7 @@ linter:
- prefer_final_in_for_each
- prefer_final_locals
- prefer_for_elements_to_map_fromIterable
- prefer_foreach
- prefer_function_declarations_over_variables
- prefer_generic_function_type_aliases
- prefer_if_elements_to_conditional_expressions
Expand All @@ -132,6 +140,7 @@ linter:
- prefer_is_not_empty
- prefer_is_not_operator
- prefer_iterable_whereType
- prefer_mixin
- prefer_null_aware_method_calls
- prefer_null_aware_operators
- prefer_single_quotes
Expand All @@ -141,32 +150,39 @@ linter:
- provide_deprecation_message
- public_member_api_docs
- recursive_getters
- remove_deprecations_in_breaking_versions
- require_trailing_commas
- secure_pubspec_urls
- simple_directive_paths
- sized_box_for_whitespace
- sized_box_shrink_expand
- slash_for_doc_comments
- sort_child_properties_last
- sort_constructors_first
- sort_pub_dependencies
- sort_unnamed_constructors_first
- strict_top_level_inference
- switch_on_type
- test_types_in_equals
- throw_in_finally
- tighten_type_of_initializing_formals
- type_annotate_public_apis
- type_init_formals
- type_literal_in_constant_pattern
- unawaited_futures
- unnecessary_await_in_return
- unnecessary_brace_in_string_interps
- unnecessary_breaks
- unnecessary_const
- unnecessary_constructor_name
- unnecessary_getters_setters
- unnecessary_ignore
- unnecessary_lambdas
- unnecessary_late
- unnecessary_library_directive
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_aware_operator_on_extension_on_nullable
- unnecessary_null_checks
- unnecessary_null_in_if_null_operators
- unnecessary_nullable_for_final_variable_declarations
Expand All @@ -178,17 +194,21 @@ linter:
- unnecessary_string_interpolations
- unnecessary_this
- unnecessary_to_list_in_spreads
- unnecessary_unawaited
- unnecessary_underscores
- unreachable_from_main
- unrelated_type_equality_checks
- use_build_context_synchronously
- use_colored_box
- use_decorated_box
- use_enums
- use_full_hex_values_for_flutter_colors
- use_function_type_syntax_for_parameters
- use_if_null_to_convert_nulls_to_bools
- use_is_even_rather_than_modulo
- use_key_in_widget_constructors
- use_late_for_private_fields_and_variables
- use_named_constants
- use_null_aware_elements
- use_raw_strings
- use_rethrow_when_possible
- use_setters_to_change_properties
Expand All @@ -197,5 +217,7 @@ linter:
- use_super_parameters
- use_test_throws_matchers
- use_to_and_as_if_applicable
- use_truncating_division
- valid_regexps
- var_with_no_type_annotation
- void_checks
7 changes: 3 additions & 4 deletions example/main.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// ignore_for_file: avoid_print

import 'package:equatable/equatable.dart';

class Credentials extends Equatable {
class Credentials with Equatable {
const Credentials({required this.username, required this.password});

final String username;
Expand All @@ -15,7 +14,7 @@ class Credentials extends Equatable {
bool get stringify => false;
}

class EquatableDateTime extends DateTime with EquatableMixin {
class EquatableDateTime extends DateTime with Equatable {
EquatableDateTime(
super.year, [
super.month,
Expand Down Expand Up @@ -49,7 +48,7 @@ void main() {
print(credentialsB == credentialsC); // true
print(credentialsA); // Credentials

// Equatable Mixin
// Mixin Equatable
final dateTimeA = EquatableDateTime(2019);
final dateTimeB = EquatableDateTime(2019, 2, 20, 19, 46);
final dateTimeC = EquatableDateTime(2019, 2, 20, 19, 46);
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: example

environment:
sdk: ">=3.5.0 <4.0.0"
sdk: ^3.12.0

dependencies:
equatable:
Expand Down
6 changes: 3 additions & 3 deletions lib/equatable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
/// `==` operators or `hashCode`s.
library equatable;

export './src/equatable.dart';
export './src/equatable_config.dart';
export './src/equatable_mixin.dart';
export 'src/equatable.dart';
export 'src/equatable_config.dart';
export 'src/equatable_mixin.dart';
9 changes: 7 additions & 2 deletions lib/src/equatable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ import 'package:meta/meta.dart';
/// List<Object> get props => [name];
/// }
/// ```
///
/// Equatable can also be used as a mixin
///
/// ```dart
/// class Person with Equatable {...}
/// ```
/// {@endtemplate}
@immutable
abstract class Equatable {
abstract mixin class Equatable {
/// {@macro equatable}
const Equatable();

Expand All @@ -38,7 +44,6 @@ abstract class Equatable {
/// `EquatableConfig.stringify` will be used instead. This defaults to
/// `false`.
/// {@endtemplate}
// ignore: avoid_returning_null
bool? get stringify => null;

@override
Expand Down
1 change: 0 additions & 1 deletion lib/src/equatable_config.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// ignore_for_file: avoid_classes_with_only_static_members
import 'package:equatable/src/equatable.dart';

/// The default configuration for all [Equatable] instances.
Expand Down
2 changes: 1 addition & 1 deletion lib/src/equatable_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import 'package:meta/meta.dart';
///
/// Like with extending [Equatable], the [EquatableMixin] overrides the
/// [operator ==] as well as the [hashCode] based on the provided [props].
@Deprecated('use Equatable as a mixin instead')
@immutable
mixin EquatableMixin {
/// {@macro equatable_props}
List<Object?> get props;

/// {@macro equatable_stringify}
// ignore: avoid_returning_null
bool? get stringify => null;

@override
Expand Down
1 change: 1 addition & 0 deletions lib/src/equatable_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ bool objectsEquals(Object? a, Object? b) {

@pragma('vm:prefer-inline')
bool _isEquatable(Object? object) {
// ignore: deprecated_member_use_from_same_package
return object is Equatable || object is EquatableMixin;
}

Expand Down
8 changes: 4 additions & 4 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ topics: [equality, equals]
funding: [https://github.com/sponsors/felangel]

environment:
sdk: ">=2.12.0 <4.0.0"
sdk: ">=3.0.0 <4.0.0"

dependencies:
collection: ^1.15.0
meta: ^1.3.0
collection: ^1.0.0
meta: ^1.0.0

dev_dependencies:
test: ^1.16.0
test: ^1.0.0

screenshots:
- description: The equatable package logo.
Expand Down
1 change: 1 addition & 0 deletions test/equatable_config_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class Credentials extends Equatable {
bool? get stringify => shouldStringify;
}

// ignore: deprecated_member_use_from_same_package
abstract class EquatableBase with EquatableMixin {}

class CredentialsMixin extends EquatableBase {
Expand Down
Loading