diff --git a/enhanced_enums/.gitignore b/enhanced_enums/.gitignore new file mode 100644 index 0000000..3c8a157 --- /dev/null +++ b/enhanced_enums/.gitignore @@ -0,0 +1,6 @@ +# Files and directories created by pub. +.dart_tool/ +.packages + +# Conventional directory for build output. +build/ diff --git a/enhanced_enums/README.md b/enhanced_enums/README.md new file mode 100644 index 0000000..f25bf58 --- /dev/null +++ b/enhanced_enums/README.md @@ -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. diff --git a/enhanced_enums/analysis_options.yaml b/enhanced_enums/analysis_options.yaml new file mode 100644 index 0000000..572dd23 --- /dev/null +++ b/enhanced_enums/analysis_options.yaml @@ -0,0 +1 @@ +include: package:lints/recommended.yaml diff --git a/enhanced_enums/lib/comparable.dart b/enhanced_enums/lib/comparable.dart new file mode 100644 index 0000000..4f87675 --- /dev/null +++ b/enhanced_enums/lib/comparable.dart @@ -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 { + zero(0), + one(1), + many(99); + + final int quantity; + + const Ordering(this.quantity); + + @override + int compareTo(Ordering other) => quantity - other.quantity; +} diff --git a/enhanced_enums/lib/comparable_mixin.dart b/enhanced_enums/lib/comparable_mixin.dart new file mode 100644 index 0000000..e9d50e2 --- /dev/null +++ b/enhanced_enums/lib/comparable_mixin.dart @@ -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 { + zero, + few, + many; +} + +/// Mixin that uses the enum index to create a comparable +mixin EnumIndexOrdering on Enum implements Comparable { + @override + int compareTo(T other) => index - other.index; +} diff --git a/enhanced_enums/lib/complete_example.dart b/enhanced_enums/lib/complete_example.dart new file mode 100644 index 0000000..4650dc8 --- /dev/null +++ b/enhanced_enums/lib/complete_example.dart @@ -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 { + 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!'; + } +} diff --git a/enhanced_enums/lib/members.dart b/enhanced_enums/lib/members.dart new file mode 100644 index 0000000..f0c32a3 --- /dev/null +++ b/enhanced_enums/lib/members.dart @@ -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)'; +} diff --git a/enhanced_enums/lib/plain.dart b/enhanced_enums/lib/plain.dart new file mode 100644 index 0000000..6a4ded0 --- /dev/null +++ b/enhanced_enums/lib/plain.dart @@ -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 } diff --git a/enhanced_enums/lib/typed_enum.dart b/enhanced_enums/lib/typed_enum.dart new file mode 100644 index 0000000..919f1f9 --- /dev/null +++ b/enhanced_enums/lib/typed_enum.dart @@ -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 { + numbers([1, 2, 3]), + strings(['A', 'B', 'C']); + + final List items; + + const EnumWithType(this.items); +} diff --git a/enhanced_enums/pubspec.yaml b/enhanced_enums/pubspec.yaml new file mode 100644 index 0000000..19bf73f --- /dev/null +++ b/enhanced_enums/pubspec.yaml @@ -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 diff --git a/enhanced_enums/test/comparable_mixin_test.dart b/enhanced_enums/test/comparable_mixin_test.dart new file mode 100644 index 0000000..e74a088 --- /dev/null +++ b/enhanced_enums/test/comparable_mixin_test.dart @@ -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]); + }); +} diff --git a/enhanced_enums/test/comparable_test.dart b/enhanced_enums/test/comparable_test.dart new file mode 100644 index 0000000..bc0d80c --- /dev/null +++ b/enhanced_enums/test/comparable_test.dart @@ -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]); + }); +} diff --git a/enhanced_enums/test/complete_example_test.dart b/enhanced_enums/test/complete_example_test.dart new file mode 100644 index 0000000..79e8fb0 --- /dev/null +++ b/enhanced_enums/test/complete_example_test.dart @@ -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!'); + }); +} diff --git a/enhanced_enums/test/members_test.dart b/enhanced_enums/test/members_test.dart new file mode 100644 index 0000000..65f9a8d --- /dev/null +++ b/enhanced_enums/test/members_test.dart @@ -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)'); + }); +} diff --git a/enhanced_enums/test/plain_test.dart b/enhanced_enums/test/plain_test.dart new file mode 100644 index 0000000..117d5f0 --- /dev/null +++ b/enhanced_enums/test/plain_test.dart @@ -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]); + }); +} diff --git a/enhanced_enums/test/typed_enum_test.dart b/enhanced_enums/test/typed_enum_test.dart new file mode 100644 index 0000000..c828ee9 --- /dev/null +++ b/enhanced_enums/test/typed_enum_test.dart @@ -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']); + }); +}