All Projects → felangel → Equatable

felangel / Equatable

Licence: mit
A Dart package that helps to implement value based equality without needing to explicitly override == and hashCode.

Programming Languages

dart
5743 projects
dartlang
94 projects

Projects that are alternatives of or similar to Equatable

osma
An open source mobile agent for achieving SSI
Stars: ✭ 41 (-91.6%)
Mutual labels:  identity
Awesome Falsehood
😱 Falsehoods Programmers Believe in
Stars: ✭ 16,614 (+3304.51%)
Mutual labels:  identity
Aws Security Workshops
A collection of the latest AWS Security workshops
Stars: ✭ 332 (-31.97%)
Mutual labels:  identity
Identity Address DB
(China) 1. MySQL 身份证 地区 数据库(包含已被合并的区县,详见README) 2. PHP 验证身份证号是否正确 3. 从身份证号中获取 性别 生日 年龄 出生地 等信息 4.路过留个star
Stars: ✭ 38 (-92.21%)
Mutual labels:  identity
Identityserver4aspnetcoreidentitytemplate
An ASP.NET Core 3.1 IdentityServer4 Identity Bootstrap 4 template with localization
Stars: ✭ 262 (-46.31%)
Mutual labels:  identity
Hugo Awesome Identity
😤 Awesome Identity is a single-page Hugo theme to introduce yourself.
Stars: ✭ 301 (-38.32%)
Mutual labels:  identity
PyVGGFace
VGG-Face CNN descriptor in PyTorch.
Stars: ✭ 21 (-95.7%)
Mutual labels:  identity
Product Is
Welcome to the WSO2 Identity Server source code! For info on working with the WSO2 Identity Server repository and contributing code, click the link below.
Stars: ✭ 435 (-10.86%)
Mutual labels:  identity
Openstack4j
A Fluent OpenStack SDK / Client Library for Java
Stars: ✭ 271 (-44.47%)
Mutual labels:  identity
Aspnetcore Webapi Course
Professional REST API design with ASP.NET Core 3.1 WebAPI
Stars: ✭ 323 (-33.81%)
Mutual labels:  identity
aragon-id
Aragon's simple identity solution to allow easy and secure ENS name assignments
Stars: ✭ 26 (-94.67%)
Mutual labels:  identity
Kratos
Next-gen identity server (think Auth0, Okta, Firebase) with Ory-hardened authentication, MFA, FIDO2, profile management, identity schemas, social sign in, registration, account recovery, and IoT auth. Golang, headless, API-only - without templating or theming headaches.
Stars: ✭ 4,684 (+859.84%)
Mutual labels:  identity
Aspnetcoreapistarter
An ASP.NET Core (v2.1) Web API project to quickly bootstrap new projects. Includes Identity, JWT authentication w/ refresh tokens.
Stars: ✭ 304 (-37.7%)
Mutual labels:  identity
magic-admin-python
Magic admin Python SDK makes it easy to leverage Decentralized ID tokens to protect routes and restricted resources for your application.
Stars: ✭ 20 (-95.9%)
Mutual labels:  identity
Scatterwebextension
Extension that allows you to sign transactions with your private keys securely from within the browser without ever exposing them.
Stars: ✭ 359 (-26.43%)
Mutual labels:  identity
syscoin
Syscoin is a crypto currency that is universally merge-mineable and offers a unique variety of services including decentralized identities, asset token issuance platform capabilities directly on the blockchain and trustless 0-counterparty interoptibility with the Ethereum blockchain
Stars: ✭ 152 (-68.85%)
Mutual labels:  identity
Uport Connect
Main uPort library for front end developers
Stars: ✭ 295 (-39.55%)
Mutual labels:  identity
Spring Boot Security Saml Sample
SBS3 — A sample SAML 2.0 Service Provider built on Spring Boot.
Stars: ✭ 469 (-3.89%)
Mutual labels:  identity
Ockam
End-to-end encrypted messaging and mutual authentication between cloud and edge-device applications
Stars: ✭ 395 (-19.06%)
Mutual labels:  identity
Django Oidc Provider
OpenID Connect and OAuth2 provider implementation for Djangonauts.
Stars: ✭ 320 (-34.43%)
Mutual labels:  identity
logo

Simplify Equality Comparisons

Build Status Code Coverage Pub Package
Star on GitHub style: effective dart Discord MIT License


Overview

Being able to compare objects in Dart often involves having to override the == operator as well as hashCode.

Not only is it verbose and tedious, but failure to do so can lead to inefficient code which does not behave as we expect.

By default, == returns true if two objects are the same instance.

Let's say we have the following class:

class Person {
  const Person(this.name);

  final String name;
}

We can create create instances of Person like so:

void main() {
  final Person bob = Person("Bob");
}

Later if we try to compare two instances of Person either in our production code or in our tests we will run into a problem.

print(bob == Person("Bob")); // false

For more information about this, you can check out the official Dart Documentation.

In order to be able to compare two instances of Person we need to change our class to override == and hashCode like so:

class Person {
  const Person(this.name);

  final String name;

  @override
  bool operator ==(Object other) =>
    identical(this, other) ||
    other is Person &&
    runtimeType == other.runtimeType &&
    name == other.name;

  @override
  int get hashCode => name.hashCode;
}

Now if we run the following code again:

print(bob == Person("Bob")); // true

it will be able to compare different instances of Person.

You can see how this can quickly become a hassle when dealing with complex classes. This is where Equatable comes in!

What does Equatable do?

Equatable overrides == and hashCode for you so you don't have to waste your time writing lots of boilerplate code.

There are other packages that will actually generate the boilerplate for you; however, you still have to run the code generation step which is not ideal.

With Equatable there is no code generation needed and we can focus more on writing amazing applications and less on mundane tasks.

Usage

First, we need to do add equatable to the dependencies of the pubspec.yaml

dependencies:
  equatable: ^2.0.0

Next, we need to install it:

# Dart
pub get

# Flutter
flutter packages get

Lastly, we need to extend Equatable

import 'package:equatable/equatable.dart';

class Person extends Equatable {
  const Person(this.name);

  final String name;

  @override
  List<Object> get props => [name];
}

When working with json:

import 'package:equatable/equatable.dart';

class Person extends Equatable {
  const Person(this.name);

  final String name;

  @override
  List<Object> get props => [name];

  factory Person.fromJson(Map<String, dynamic> json) {
    return Person(json['name']);
  }
}

We can now compare instances of Person just like before without the pain of having to write all of that boilerplate. Note: Equatable is designed to only work with immutable objects so all member variables must be final (This is not just a feature of Equatable - overriding a hashCode with a mutable value can break hash-based collections).

Equatable also supports const constructors:

import 'package:equatable/equatable.dart';

class Person extends Equatable {
  const Person(this.name);

  final String name;

  @override
  List<Object> get props => [name];
}

toString Implementation

Equatable can implement toString method including all the given props. If you want that behaviour for a specific Equatable object, just include the following:

@override
bool get stringify => true;

For instance:

import 'package:equatable/equatable.dart';

class Person extends Equatable {
  const Person(this.name);

  final String name;

  @override
  List<Object> get props => [name];

  @override
  bool get stringify => true;
}

For the name Bob, the output will be:

Person(Bob)

This flag by default is false and toString will return just the type:

Person

EquatableConfig

stringify can also be configured globally for all Equatable instances via EquatableConfig

EquatableConfig.stringify = true;

If stringify is overridden for a specific Equatable class, then the value of EquatableConfig.stringify is ignored. In other words, the local configuration always takes precedence over the global configuration.

Note: EquatableConfig.stringify defaults to true in debug mode and false in release mode.

Recap

Without Equatable

class Person {
  const Person(this.name);

  final String name;

  @override
  bool operator ==(Object other) =>
    identical(this, other) ||
    other is Person &&
    runtimeType == other.runtimeType &&
    name == other.name;

  @override
  int get hashCode => name.hashCode;
}

With Equatable

import 'package:equatable/equatable.dart';

class Person extends Equatable {
  const Person(this.name);

  final String name;

  @override
  List<Object> get props => [name];
}

EquatableMixin

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.

Usage

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

class EquatableDateTime extends DateTime with EquatableMixin {
  EquatableDateTime(
    int year, [
    int month = 1,
    int day = 1,
    int hour = 0,
    int minute = 0,
    int second = 0,
    int millisecond = 0,
    int microsecond = 0,
  ]) : super(year, month, day, hour, minute, second, millisecond, microsecond);

  @override
  List<Object> get props {
    return [year, month, day, hour, minute, second, millisecond, microsecond];
  }
}

Now if we want to create a subclass of EquatableDateTime, we can just override props.

class EquatableDateTimeSubclass extends EquatableDateTime {
  final int century;

  EquatableDateTimeSubclass(
    this.century,
    int year,[
    int month = 1,
    int day = 1,
    int hour = 0,
    int minute = 0,
    int second = 0,
    int millisecond = 0,
    int microsecond = 0,
  ]) : super(year, month, day, hour, minute, second, millisecond, microsecond);

  @override
  List<Object> get props => super.props..addAll([century]);
}

Performance

You might be wondering what the performance impact will be if you use Equatable.

Results (average over 10 runs)

Equality Comparison A == A

Class Runtime (μs)
Manual 0.193
Empty Equatable 0.191
Hydrated Equatable 0.190

Instantiation A()

Class Runtime (μs)
Manual 0.165
Empty Equatable 0.181
Hydrated Equatable 0.182

*Performance Tests run using: Dart VM version: 2.4.0

Maintainers

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].