Add `enum_field_rename` option in build.yaml for default enum value renaming
### Summary
Adds an **`enum_field_rename`** option to the `json_serializable` builder config so packages can set a default field-rename strategy for enum values (e.g. PascalCase from the backend) without annotating every enum with `@JsonEnum(fieldRename: ...)`.
Fixes [#1021](https://github.com/google/json_serializable.dart/issues/1021).
### Problem
`field_rename` in `build.yaml` only affects **class fields**, not **enum value names**. Enums had to set `@JsonEnum(fieldRename: ...)` on each type. There was no way to configure a package-wide default for enum value renaming.
### Solution
Introduce a separate option **`enum_field_rename`** in the build config. When generating enum value maps:
- If `@JsonEnum(fieldRename: ...)` is set to something other than `none`, that value is used.
- Otherwise, the build config **`enum_field_rename`** is used (default `none`).
### Changes
**json_annotation**
- Added optional `enumFieldRename` to `JsonSerializable` (used when parsing `build.yaml`).
- Updated generated `json_serializable.g.dart` for `fromJson`/`toJson` and allowed keys.
**json_serializable**
- **ClassConfig**: Added `enumFieldRename` (default `FieldRename.none`) and wired it from `JsonSerializable` and in `mergeConfig`.
- **enum_utils**: `enumValueMapFromType` (and helpers) accept optional `defaultEnumFieldRename`; effective rename is annotation value if non-`none`, else config default, else `none`.
- **JsonEnumGenerator**: Takes `Settings` and passes `config.enumFieldRename` as the default for enums.
- **EnumHelper / encoder_helper**: Pass `context.config.enumFieldRename` (or `config.enumFieldRename`) into enum helpers so the default is applied when encoding/decoding enum fields.
### Examples
**1. build.yaml – default PascalCase for all enums**
```yaml
targets:
$default:
builders:
json_serializable:
options:
enum_field_rename: pascal
```
Enums without `@JsonEnum(fieldRename: ...)` (or with `fieldRename: none`) will serialize with PascalCase:
```dart
// No per-enum annotation needed
enum Status { active, pending, completed }
// Serializes as: "Active", "Pending", "Completed"
```
**2. Per-enum override**
```dart
@JsonEnum(fieldRename: FieldRename.snake)
enum ApiStatus { active, pending }
// Uses snake_case: "active", "pending" (annotation overrides build config)
```
**3. Same options as other build config**
```yaml
targets:
$default:
builders:
json_serializable:
options:
field_rename: snake # class fields → snake_case
enum_field_rename: pascal # enum values → PascalCase
```
**4. Supported values**
Same as `field_rename`: `none`, `kebab`, `snake`, `pascal`, `screamingSnake`.
### Documentation
- **README.md** and **tool/readme/readme_template.md**: Document `enum_field_rename: none` in the build configuration options.
- In YAML use **snake_case** (`enum_field_rename`); in Dart use **camelCase** (`enumFieldRename`), consistent with `field_rename` / `fieldRename`.
### Testing
- **config_test.dart**: `enum_field_rename` in default config, invalid config handling, and key ordering.
- **shared_config.dart**: Non-default `enumFieldRename` in `generatorConfigNonDefaultJson`.
- **test_sources.dart**: `ConfigurationExplicitDefaults` includes `enumFieldRename: FieldRename.none` so annotation-over-config behavior is tested.
- **json_serializable_test.dart**: `JsonEnumGenerator` updated to use `JsonEnumGenerator(Settings())` so enum generation uses the new default.
All existing tests pass (624 tests).
fixes #1021
合并状态:未合并 2 条评论