option_set 0.0.1

  • Readme
  • Changelog
  • Example
  • Installing
  • 50

OptionSet #

A Dart package for working with option sets (i.e. bitmasks).

Example #

@option_set
enum _ImageFormat { png, jpeg, svg, gif }

// Type-safe, easy-to-read construction
ImageFormat acceptedFormats = ImageFormat.png & ImageFormat.jpeg;
print(acceptedFormats); // ImageFormat (0011): png, jpeg

// Querying
acceptedFormats.has(ImageFormat.png); // true
acceptedFormats.has(ImageFormat.gif); // false

// Negation
ImageFormat nonAcceptedFormats = ~acceptedFormats;

// ... and more!

Table of Contents #

Installation #

See [https://pub.dev/packages/option-set#-installing-tab-] on how to install dart packages.

Creating an OptionSet

Automatic using build_runner

@option_set
enum _ImageFormat {
  png,
  jpeg,
  svg,
  gif
}

See Automatic Generation for how to setup auto-generation of option sets!

Manual #

class ImageFormat extends OptionSet<ImageFormat> { // (1)
  const ImageFormat._(rawValue) : super(rawValue); // (2)

  // OPTIONS //
  static final png = const ImageFormat._(1 << 0); // (3)
  static final jpeg = const ImageFormat._(1 << 1);
  static final svg = const ImageFormat._(1 << 2);
  static final gif = const ImageFormat._(1 << 3);

  // COMPOUND OPTIONS
  static final rasters = png & jpeg;
  
  // CONVENIENCE OPTIONS
  static final none = const ImageFormat._(0); // (4)
  static final all = png & jpeg & svg & gif;
  
  @override
  final List<String> optionNames = const [ // (5)
    'png', 'jpeg', 'svg', 'gif'
  ];

  @override
  ImageFormat initWithRawValue(int rawValue) { // (6)
    return ImageFormat._(rawValue);
  }
}
  1. Define a new class and extend OptionSet with the new class as the type parameter for OptionSet.

  2. Implement a const constructor (ideally private) that calls the OptionSet constructor

  3. Add the options to the class as static final values using the bitwise shift convention shown in the example.

  4. (Optional) Define none and/or all options.

  5. Override optionNames.

  6. Override initWithRawValue.

Usage #

Construction #

ImageFormat acceptedFormats = ImageFormat.png;
print(acceptedFormats); // ImageFormat (0001): png

ImageFormat rasterFormats = ImageFormat.png & ImageFormat.jpeg;
print(acceptedFormats); // ImageFormat (0011): png, jpeg

Combination #

acceptedFormats = acceptedFormats & ImageFormat.jpeg;
print(acceptedFormats); // ImageFormat (0011): png, jpeg

Negation #

ImageFormat nonAcceptedFormats = ~acceptedFormats;
print(nonAcceptedFormats); // ImageFormat (1100): svg, gif

Querying #

// Single
bool isSvgAccepted = acceptedFormats.has(ImageFormat.svg);
print(isSvgAccepted); // false

bool isPngAccepted = acceptedFormats.has(ImageFormat.png);
print(isPngAccepted); // true

// Compound
bool areBothSvgAndPngAccepted =
acceptedFormats.has(ImageFormat.svg & ImageFormat.png);
print(areBothSvgAndPngAccepted); // false

bool areBothJpegAndPngAccepted =
acceptedFormats.has(ImageFormat.jpeg & ImageFormat.png);
print(areBothJpegAndPngAccepted); // true

Toggling #

// Single
acceptedFormats.toggle(ImageFormat.gif); 
print(acceptedFormats); // ImageFormat (1011): png, jpeg, gif

// Compound
acceptedFormats = acceptedFormats.toggle(ImageFormat.gif & ImageFormat.svg);
print(acceptedFormats); // ImageFormat (0111): png, jpeg, svg

Turn off #

// Single
acceptedFormats = acceptedFormats.turnOff(ImageFormat.png);
print(acceptedFormats); // ImageFormat (0110): jpeg, svg

// Compound
acceptedFormats = acceptedFormats.turnOff(ImageFormat.jpeg & ImageFormat.svg);
print(acceptedFormats); // ImageFormat (0000):

Equality #

OptionSet otherEmptyOptionSet = OptionSet(0);
print(acceptedFormats.rawValue == otherEmptyOptionSet.rawValue); // true
print(acceptedFormats == otherEmptyOptionSet); // fa

ImageFormat otherEmptyImageFormat = ImageFormat.none;
print(acceptedFormats == otherEmptyImageFormat); // true

Auto-generation of OptionSet

To take full advantage of this package, use the build_runner package along with the @option_set annotation to auto-generate the boilerplate code needed to extend OptionSet:

pubspec.yaml (in project root)

dependencies:
  option_set: ^0.0.1

dev_dependencies:
  build_runner: ^1.0.0
  build_verify: ^1.1.0

build.yaml (in project root)

targets:
  $default:
    builders:
      option_set|option_set:
        generate_for:
          - lib/generator_example.dart

lib/generator_example.dart

import 'package:option_set/option_set.dart';
part 'generator_example.g.dart';

@option_set
enum _ImageFormat {
  png,
  jpeg,
  svg,
  gif,
}

Terminal

cd $PROJECT_ROOT
pub run build_runner build

Configuration #

If you only need a bare-bones OptionSet, then just use the @option_set annotation. However, if you want a more complex implementation, use the @Option_Set annotation!

The @Option_Set annotation takes 4 optional parameters:

@Option_Set((
  String name,
  Map<String, List<Object>> compound,
  bool includeNone,
  bool includeAll,
})

// Example
@Option_Set(
  name: 'USPSShippingOptions',
  compound: {'express': [_ShippingOptions.nextDay, _ShippingOptions.secondDay],},
  includeNone: true,
  includeAll: true
)
enum _ShippingOptions {
  nextDay,
  secondDay,
  priority,
  standard
}

name #

Name to use for generated option set.

If not set, will look at annotated enum name. If the enum name starts with _, the generated option set name will be the enum name minus the leading _. Otherwise, the option set name will be the enum name with Options appended to it.

compound #

Map of compound option names to a list of the enum values to use to construct the compound option.

Example:

compound: {'rasters: [_ImageFormat.png, _ImageFormat.jpeg]}

includeNone #

If true, will generate a none option. Defaults to false.

includeAll #

If true, will generate an all option. Defaults to false.

[0.0.1] - Aug 4, 2019.

Initial Release #

  • OptionSet class
  • Generator for OptionSet

example/lib/example.dart

import 'package:option_set/option_set.dart';

class ImageFormat extends OptionSet<ImageFormat> {
  const ImageFormat._(rawValue) : super(rawValue);

  // OPTIONS //
  static final png = const ImageFormat._(1 << 0);
  static final jpeg = const ImageFormat._(1 << 1);
  static final svg = const ImageFormat._(1 << 2);
  static final gif = const ImageFormat._(1 << 3);

  static final rasters = png & jpeg;

  @override
  final List<String> optionNames = const ['png', 'jpeg', 'svg', 'gif'];

  @override
  ImageFormat initWithRawValue(int rawValue) {
    return ImageFormat._(rawValue);
  }
}

// Example usages
void main() {
  // Construction
  ImageFormat acceptedFormats = ImageFormat.png;
  print(acceptedFormats); // ImageFormat (0001): png

  // Combination
  acceptedFormats = acceptedFormats & ImageFormat.jpeg;
  print(acceptedFormats); // ImageFormat (0011): png, jpeg

  // Negation
  ImageFormat nonAcceptedFormats = ~acceptedFormats;
  print(nonAcceptedFormats); // ImageFormat (1100): svg, gif

  // Query (Single)
  bool isSvgAccepted = acceptedFormats.has(ImageFormat.svg);
  print(isSvgAccepted); // false

  bool isPngAccepted = acceptedFormats.has(ImageFormat.png);
  print(isPngAccepted); // true

  // Query (Compound)
  bool areBothSvgAndPngAccepted =
    acceptedFormats.has(ImageFormat.svg & ImageFormat.png);
  print(areBothSvgAndPngAccepted); // false

  bool areBothJpegAndPngAccepted =
    acceptedFormats.has(ImageFormat.jpeg & ImageFormat.png);
  print(areBothJpegAndPngAccepted); // true

  // Toggle (Single)
  acceptedFormats = acceptedFormats.toggle(ImageFormat.gif);
  print(acceptedFormats); // ImageFormat (1011): png, jpeg, gif

  // Toggle (Compound)
  acceptedFormats = acceptedFormats.toggle(ImageFormat.gif & ImageFormat.svg);
  print(acceptedFormats); // ImageFormat (0111): png, jpeg, svg

  // Turn off (Single)
  acceptedFormats = acceptedFormats.turnOff(ImageFormat.png);
  print(acceptedFormats); // ImageFormat (0110): jpeg, svg

  // Turn off (Compound)
  acceptedFormats = acceptedFormats.turnOff(ImageFormat.jpeg & ImageFormat.svg);
  print(acceptedFormats); // ImageFormat (0000):

  // ==
  OptionSet otherEmptyOptionSet = OptionSet(0);
  print(acceptedFormats.rawValue == otherEmptyOptionSet.rawValue); // true
  print(acceptedFormats == otherEmptyOptionSet); // false!

  ImageFormat otherEmptyImageFormat = ImageFormat._(0);
  print(acceptedFormats == otherEmptyImageFormat); // true
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  option_set: ^0.0.1

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:option_set/option_set.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
9
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
80
Overall:
Weighted score of the above. [more]
50
Learn more about scoring.

We analyzed this package on Oct 16, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.5.1
  • pana: 0.12.21

Platforms

Detected platforms: Flutter, web, other

No platform restriction found in primary library package:option_set/option_set.dart.

Health suggestions

Format lib/option_set.dart.

Run dartfmt to format lib/option_set.dart.

Format lib/src/generator/annotation.dart.

Run dartfmt to format lib/src/generator/annotation.dart.

Format lib/src/generator/builder.dart.

Run dartfmt to format lib/src/generator/builder.dart.

Format lib/src/generator/generator.dart.

Run dartfmt to format lib/src/generator/generator.dart.

Format lib/src/option_set.dart.

Run dartfmt to format lib/src/option_set.dart.

Maintenance issues and suggestions

Support latest dependencies. (-10 points)

The version constraint in pubspec.yaml does not support the latest published versions for 1 dependency (analyzer).

Package is pre-v0.1 release. (-10 points)

While nothing is inherently wrong with versions of 0.0.*, it might mean that the author is still experimenting with the general direction of the API.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
analyzer ^0.36.3 0.36.4 0.38.5
build ^1.1.4 1.2.0
code_builder ^3.2.0 3.2.0
dart_style ^1.2.9 1.2.9 1.3.1
source_gen ^0.9.4 0.9.4+4 0.9.4+5
Transitive dependencies
args 1.5.2
async 2.4.0
built_collection 4.2.2
built_value 6.7.1
charcode 1.1.2
collection 1.14.12
convert 2.1.1
crypto 2.1.3
csslib 0.16.1
fixnum 0.10.9
front_end 0.1.19 0.1.27
glob 1.2.0
html 0.14.0+3
js 0.6.1+1
kernel 0.3.19 0.3.27
logging 0.11.3+2
matcher 0.12.5
meta 1.1.7
node_interop 1.0.3
node_io 1.0.1+2
package_config 1.1.0
path 1.6.4
pedantic 1.8.0+1
pub_semver 1.4.2
quiver 2.0.5
source_span 1.5.5
stack_trace 1.9.3
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6
watcher 0.9.7+12
yaml 2.2.0
Dev dependencies
test ^1.6.5