blob: 1594380753585e4589456d7d2da3ab383857e4f8 [file] [edit]
// Copyright (c) 2023, 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:build/build.dart';
import 'package:glob/glob.dart';
import 'package:yaml/yaml.dart';
/// Options for the message data file and code generation.
class GenerationOptions {
/// Whether to generate named message calls. Example:
/// An arb file like this
/// ```json
/// {
/// "helloName": "Hello {name}"
/// }
/// ```
/// leads to
/// ```dart
/// String helloName(String name) {
/// ```
/// being generated.
final bool messageCalls;
/// Whether to generate a method to fetch a message by its id. Leads to the
/// ids being stored in the data file.
final bool findById;
/// How the messages should be indexed, either through `int`s or an `enum`
final IndexType indexType;
/// The data file serialization, either json or (TBD) binary.
final SerializationType serialization;
/// The data file deserialization, either through browser functionalities or
/// dart native code.
final DeserializationType deserialization;
/// The header to add to all generated files, for example for licensing.
final String header;
/// The origin of the algorithm for determining which plural case to use.
final PluralSelectorType pluralSelector;
GenerationOptions({
required this.serialization,
required this.deserialization,
required this.messageCalls,
required this.findById,
required this.indexType,
required this.header,
required this.pluralSelector,
});
static Future<GenerationOptions> fromPubspec(String pubspecData) async {
final pubspec = loadYaml(pubspecData) as YamlMap;
final packageOptions = pubspec['package_options'] as YamlMap?;
final messagesOptions = packageOptions?['messages_builder'] as YamlMap?;
final generationOptions = GenerationOptions(
serialization: SerializationType.json,
deserialization: DeserializationType.web,
messageCalls: (messagesOptions?['generateMethods'] as bool?) ?? true,
findById: (messagesOptions?['generateFindById'] as bool?) ?? false,
indexType: _indexType(messagesOptions),
header: messagesOptions?['header'] as String? ??
'Generated by package:messages_builder.',
pluralSelector: _pluralSelector(messagesOptions),
);
return generationOptions;
}
static Future<String> getPubspecFrom(BuildStep buildStep) async {
final pubspecId = await buildStep.findAssets(Glob('pubspec.yaml')).first;
final pubspecData = await buildStep.readAsString(pubspecId);
return pubspecData;
}
static IndexType _indexType(YamlMap? messagesOptions) {
final generateFindString = messagesOptions?['generateFindBy'] as String?;
return generateFindString != null
? IndexType.values
.where((type) => type.name == generateFindString)
.first
: IndexType.integer;
}
static PluralSelectorType _pluralSelector(YamlMap? messagesOptions) {
final pluralSelectorString = messagesOptions?['pluralSelector'] as String?;
return pluralSelectorString != null
? PluralSelectorType.values
.where((type) => type.name == pluralSelectorString)
.first
: PluralSelectorType.intl;
}
}
enum SerializationType {
json;
}
enum DeserializationType {
web;
}
/// How the indexing of the messages should be implemented.
enum IndexType {
/// No indexing.
none,
/// Indexing via a collection of `static int`s.
integer,
/// Indexing via an enum.
enumerate;
}
/// The origin of the algorithm for determining which plural case to use.
enum PluralSelectorType {
/// From `package:intl`.
intl,
/// From `package:intl4x`.
intl4x,
/// A user-specified algorithm.
custom;
}