Skip to content

Samples for enhanced enums feature #136

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Mar 25, 2022
Merged
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
6 changes: 6 additions & 0 deletions enhanced_enums/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Files and directories created by pub.
.dart_tool/
.packages

# Conventional directory for build output.
build/
20 changes: 20 additions & 0 deletions enhanced_enums/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Enhanced enums samples

This a set of samples that demonstrates the enhanced enums syntax
and shows some common use cases of the feature.

This feature is part of Dart 2.17. The programs in this folder won't
compile in earlier versions.

## Instructions

Read the source code in the `lib/` directory. The code is split into
separate files according to topics or use cases. For instance,
`lin/comparable_mixin.dart` demonstrates how a mixin can be used to add
extra functionality to an enum.

In `lib/complete_example.dart` you will find a complete example
using all the functionality from enhanced enums.

In `test/` you will find unit tests showing how the enums from the examples
can be used.
1 change: 1 addition & 0 deletions enhanced_enums/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include: package:lints/recommended.yaml
17 changes: 17 additions & 0 deletions enhanced_enums/lib/comparable.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// Enum that implements a Comparable
enum Ordering implements Comparable<Ordering> {
zero(0),
one(1),
many(99);

final int quantity;

const Ordering(this.quantity);

@override
int compareTo(Ordering other) => quantity - other.quantity;
}
16 changes: 16 additions & 0 deletions enhanced_enums/lib/comparable_mixin.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// Enum that implements a Comparable using a mixin
enum Ordering with EnumIndexOrdering<Ordering> {
zero,
few,
many;
}

/// Mixin that uses the enum index to create a comparable
mixin EnumIndexOrdering<T extends Enum> on Enum implements Comparable<T> {
@override
int compareTo(T other) => index - other.index;
}
65 changes: 65 additions & 0 deletions enhanced_enums/lib/complete_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// Complete example that showcases the different use cases for dart enums
/// in a real scenario.
///
/// Enum that represents different types of vehicles.
enum Vehicle with FlatTireMixin, Traveler implements Comparable<Vehicle> {
car(tires: 4, passengers: 5, carbonPerKilometer: 400),
bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);

const Vehicle({
required this.tires,
required this.passengers,
required this.carbonPerKilometer,
});

/// Number of tires of this Vehicle, part of [FlatTireMixin].
@override
final int tires;

/// Number of passengers the Vehicle can transport.
final int passengers;

/// Carbon in grams per kilometer.
final int carbonPerKilometer;

/// Method that calculates the Carbon Footprint of a Vehicle per passenger.
int get carbonFootprint => (carbonPerKilometer / passengers).round();

/// Comparable uses [carbonFootprint] to compare Vehicles.
@override
int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}

/// Mixin that adds extra functionality.
///
/// This Mixin introduces the [tires] member and a method [costToReplaceTires]
/// to calculate the cost of replacing the tires.
mixin FlatTireMixin {
/// Fixed fee to add to the total cost.
static const fee = 50;

/// Number of tires getter, to be implemented by Enum.
int get tires;

/// Calculates the price to replace all tires.
int costToReplaceTires({required int pricePerTire}) {
return tires * pricePerTire + fee;
}
}

/// Mixin that adds Enum specific functionality
///
/// This mixin adds the [travel] method, that returns a String
/// with the Enum name in it.
///
/// This mixin can access the property [name] from the Enum.
mixin Traveler on Enum {
String travel() {
return 'I am traveling in a $name!';
}
}
21 changes: 21 additions & 0 deletions enhanced_enums/lib/members.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// Enum with members and named constructor.
///
/// Also shows an example of [toString] override.
enum LogPriority {
warning(2, "Warning"),
error(1, "Error"),
log.unknown("Log");

const LogPriority(this.priority, this.prefix);
const LogPriority.unknown(String prefix) : this(-1, prefix);

final int priority;
final String prefix;

@override
String toString() => '$prefix($priority)';
}
8 changes: 8 additions & 0 deletions enhanced_enums/lib/plain.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// Plain enum.
///
/// This enum doesn't use any of enhancements.
enum Plain { foo, bar, baz }
15 changes: 15 additions & 0 deletions enhanced_enums/lib/typed_enum.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// Enum with a generic type.
///
/// The type [T] is used to define the type of [List] the enum contains.
enum EnumWithType<T> {
numbers<int>([1, 2, 3]),
strings<String>(['A', 'B', 'C']);

final List<T> items;

const EnumWithType(this.items);
}
12 changes: 12 additions & 0 deletions enhanced_enums/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: enhanced_enums
description: Samples that demonstrates the enhanced enums syntax

# This example isn't intended for publishing on pub.dev.
publish_to: none

environment:
sdk: '>=2.17.0-182.1.beta <3.0.0'

dev_dependencies:
lints: ^1.0.0
test: ^1.16.0
19 changes: 19 additions & 0 deletions enhanced_enums/test/comparable_mixin_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:enhanced_enums/comparable_mixin.dart';
import 'package:test/test.dart';

void main() {
test('Sort enum using compareTo in mixin', () {
// unsorted list
final list = [Ordering.many, Ordering.zero, Ordering.few];

// sort using compareTo
list.sort();

// list is sorted by amount
expect(list, [Ordering.zero, Ordering.few, Ordering.many]);
});
}
19 changes: 19 additions & 0 deletions enhanced_enums/test/comparable_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:enhanced_enums/comparable.dart';
import 'package:test/test.dart';

void main() {
test('Sort Quantity enum using compareTo', () {
// unsorted list
final list = [Ordering.many, Ordering.zero, Ordering.one];

// sort using compareTo
list.sort();

// list is sorted by amount
expect(list, [Ordering.zero, Ordering.one, Ordering.many]);
});
}
34 changes: 34 additions & 0 deletions enhanced_enums/test/complete_example_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:enhanced_enums/complete_example.dart';
import 'package:test/test.dart';

void main() {
test('Calculate efficiency of Vehicles', () {
expect(Vehicle.bicycle.carbonFootprint, 0);
expect(Vehicle.bus.carbonFootprint, 16);
expect(Vehicle.car.carbonFootprint, 80);
});

test('Sort Vehicles by carbon footprint', () {
final vehicles = Vehicle.values.toList();

// Sort using compareTo
vehicles.sort();

// Expect order from more efficient to less efficient
expect(vehicles, [Vehicle.bicycle, Vehicle.bus, Vehicle.car]);
});

test('Calculate cost to replace tires', () {
expect(Vehicle.bicycle.costToReplaceTires(pricePerTire: 10), 70);
expect(Vehicle.car.costToReplaceTires(pricePerTire: 60), 290);
expect(Vehicle.bus.costToReplaceTires(pricePerTire: 100), 650);
});

test('Travel in a car', () {
expect(Vehicle.car.travel(), 'I am traveling in a car!');
});
}
14 changes: 14 additions & 0 deletions enhanced_enums/test/members_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:enhanced_enums/members.dart';
import 'package:test/test.dart';

void main() {
test('Enum with members to String', () {
expect(LogPriority.warning.toString(), 'Warning(2)');
expect(LogPriority.error.toString(), 'Error(1)');
expect(LogPriority.log.toString(), 'Log(-1)');
});
}
24 changes: 24 additions & 0 deletions enhanced_enums/test/plain_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:enhanced_enums/plain.dart';
import 'package:test/test.dart';

void main() {
test('Plain enum names', () {
expect(Plain.foo.name, 'foo');
expect(Plain.bar.name, 'bar');
expect(Plain.baz.name, 'baz');
});

test('Plain enum index', () {
expect(Plain.foo.index, 0);
expect(Plain.bar.index, 1);
expect(Plain.baz.index, 2);
});

test('Get Plain enum values', () {
expect(Plain.values, [Plain.foo, Plain.bar, Plain.baz]);
});
}
13 changes: 13 additions & 0 deletions enhanced_enums/test/typed_enum_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:enhanced_enums/typed_enum.dart';
import 'package:test/test.dart';

void main() {
test('Use typed enum', () {
expect(EnumWithType.numbers.items, [1, 2, 3]);
expect(EnumWithType.strings.items, ['A', 'B', 'C']);
});
}