### Launch Chat Server Source: https://github.com/google/built_value.dart/blob/master/chat_example/README.md Run the chat server using the Dart VM. This command starts the backend for the chat application. ```bash dart bin/main.dart ``` -------------------------------- ### Code Generation Setup with `build_runner` Source: https://context7.com/google/built_value.dart/llms.txt Configure `pubspec.yaml` to include `build_runner` and `built_value_generator` for code generation. Run `dart run build_runner build` for a one-off build or `dart run build_runner watch` to regenerate on file changes. ```yaml # pubspec.yaml name: my_app environment: sdk: '>=3.0.0 <4.0.0' dependencies: built_collection: ^5.0.0 built_value: ^8.12.6 dev_dependencies: build_runner: ^2.4.0 built_value_generator: ^8.12.6 ``` -------------------------------- ### Setup Serializers with @SerializersFor Source: https://context7.com/google/built_value.dart/llms.txt Annotate a top-level field with `@SerializersFor` to declare a `Serializers` instance. The generator includes serializers for all field types transitively. Use this for basic serialization and deserialization of your data models. ```dart // serializers.dart import 'package:built_collection/built_collection.dart'; import 'package:built_value/serializer.dart'; import 'package:myapp/models/user.dart'; import 'package:myapp/models/post.dart'; import 'package:myapp/models/status.dart'; part 'serializers.g.dart'; @SerializersFor([ User, Post, Status, // Only root types needed; field types included transitively ]) final Serializers serializers = _$serializers; // --- Usage --- void main() { final user = User((b) => b ..id = 42 ..name = 'Bob' ..email = 'bob@example.com'); // Serialize to the built_value wire format (a List) final serialized = serializers.serialize(user); print(serialized); // [User, id, 42, name, Bob, email, bob@example.com] // Deserialize back final restored = serializers.deserialize(serialized) as User; assert(user == restored); // Type-safe convenience methods final serializedTyped = serializers.serializeWith(User.serializer, user); final restoredTyped = serializers.deserializeWith(User.serializer, serializedTyped); assert(user == restoredTyped); } ``` -------------------------------- ### Add StandardJsonPlugin for JSON Conversion Source: https://context7.com/google/built_value.dart/llms.txt Install `StandardJsonPlugin` via `SerializersBuilder.addPlugin` to convert the default list-based wire format to standard map-based JSON. This is compatible with REST APIs and supports polymorphism via a `discriminator` field. ```dart import 'dart:convert'; import 'package:built_value/serializer.dart'; import 'package:built_value/standard_json_plugin.dart'; import 'package:myapp/serializers.dart'; import 'package:myapp/models/person.dart'; // Build a serializers instance with the StandardJsonPlugin final standardSerializers = (serializers.toBuilder() ..addPlugin(StandardJsonPlugin())) .build(); void main() { // --- Serialize to standard JSON map --- final person = Person((b) => b ..id = 1 ..firstName = 'Alice' ..age = 30); // When type is known, use serializeWith — no discriminator field added final jsonMap = standardSerializers.serializeWith(Person.serializer, person); print(jsonMap); // {id: 1, firstName: Alice, age: 30} print(json.encode(jsonMap)); // {"id":1,"firstName":"Alice","age":30} // --- Deserialize from standard JSON map --- final decoded = json.decode('{"id":1,"firstName":"Alice","age":30}'); final restored = standardSerializers.deserializeWith(Person.serializer, decoded) as Person; assert(person == restored); // --- Polymorphism: serialize/deserialize without knowing the type --- // The discriminator '$' field carries the type name final serializedWithType = standardSerializers.serialize(person); // {$: Person, id: 1, firstName: Alice, age: 30} final restoredUntyped = standardSerializers.deserialize(serializedWithType) as Person; assert(person == restoredUntyped); // --- toJson / fromJson convenience --- final jsonString = standardSerializers.toJson(Person.serializer, person); final fromJsonResult = standardSerializers.fromJson(Person.serializer, jsonString); assert(person == fromJsonResult); } ``` -------------------------------- ### Serve Chat Client Source: https://github.com/google/built_value.dart/blob/master/chat_example/README.md Serve the chat client application using pub serve. This command makes the client accessible in a browser. ```bash pub serve ``` -------------------------------- ### Required File Header Source: https://github.com/google/built_value.dart/blob/master/CONTRIBUTING.md All files in the project must begin with this copyright and license header. ```dart // Copyright (c) 2015, Google Inc. 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. ``` -------------------------------- ### Clean and Rebuild Project with build_runner Source: https://context7.com/google/built_value.dart/llms.txt Use these commands to clean the build cache and rebuild your project, ensuring all generated files are up-to-date. The `--delete-conflicting-outputs` flag is useful for resolving issues with previous builds. ```bash dart run build_runner clean ``` ```bash dart run build_runner build --delete-conflicting-outputs ``` -------------------------------- ### Running `build_runner` Commands Source: https://context7.com/google/built_value.dart/llms.txt Use `dart run build_runner build` to perform a one-off code generation build. Use `dart run build_runner watch` to continuously regenerate `.g.dart` files as source files change. ```bash # One-off build — generates all .g.dart files dart run build_runner build # Watch mode — regenerates on file changes dart run build_runner watch ``` -------------------------------- ### Development Watch Mode Source: https://github.com/google/built_value.dart/blob/master/chat_example/README.md Run the development watcher to continuously update generated source files during development. This command is useful for iterating quickly on the application. ```bash dart tool/watch.dart ``` -------------------------------- ### Custom Serializer for DateTime (ISO 8601) Source: https://context7.com/google/built_value.dart/llms.txt Replaces the default `DateTime` serialization with ISO 8601 string format by adding `Iso8601DateTimeSerializer` to the `SerializersBuilder`. Only UTC `DateTime` instances are accepted for serialization. ```dart import 'package:built_value/serializer.dart'; import 'package:built_value/iso_8601_date_time_serializer.dart'; import 'package:built_value/standard_json_plugin.dart'; import 'package:myapp/serializers.dart'; // Replace default DateTime serializer with ISO 8601 final isoSerializers = (serializers.toBuilder() ..add(Iso8601DateTimeSerializer()) ..addPlugin(StandardJsonPlugin())) .build(); void main() { final dt = DateTime.utc(2024, 6, 15, 12, 30, 0); // Serialize DateTime to ISO string final serialized = isoSerializers.serializeWith( isoSerializers.serializerForType(DateTime) as PrimitiveSerializer, dt); print(serialized); // 2024-06-15T12:30:00.000Z // Deserialize from ISO string final restored = isoSerializers.deserializeWith( isoSerializers.serializerForType(DateTime) as PrimitiveSerializer, '2024-06-15T12:30:00.000Z'); assert(dt == restored); // Throws for local (non-UTC) DateTime try { isoSerializers.serializeWith( isoSerializers.serializerForType(DateTime) as PrimitiveSerializer, DateTime.now()); // not UTC } on ArgumentError catch (e) { print(e.message); // Must be in utc for serialization. } } ``` -------------------------------- ### Custom Duration Serialization with ISO 8601 Source: https://context7.com/google/built_value.dart/llms.txt Replaces default Duration serialization with ISO 8601 format. Does not support sub-second precision and will throw an error if used. ```dart import 'package:built_value/serializer.dart'; import 'package:built_value/iso_8601_duration_serializer.dart'; import 'package:myapp/serializers.dart'; final durationSerializers = (serializers.toBuilder() ..add(Iso8601DurationSerializer())) .build(); void main() { final dur = Duration(hours: 1, minutes: 30, seconds: 45); final s = durationSerializers.serializeWith( Iso8601DurationSerializer(), dur); print(s); // PT1H30M45S final roundtrip = durationSerializers.deserializeWith( Iso8601DurationSerializer(), 'PT1H30M45S'); assert(dur == roundtrip); // Zero duration final zero = durationSerializers.serializeWith( Iso8601DurationSerializer(), Duration.zero); print(zero); // PT0S // Throws for sub-second precision try { durationSerializers.serializeWith( Iso8601DurationSerializer(), Duration(milliseconds: 500)); } on ArgumentError catch (e) { print(e.message); // Contains sub-second data which cannot be serialized. } } ``` -------------------------------- ### Generate Value Type Boilerplate in Dart Source: https://github.com/google/built_value.dart/blob/master/README.md Use this live template in your text editor to generate the basic structure for a value type class. You only need to manually enter the class name. ```dart abstract class $CLASS_NAME$ implements Built<$CLASS_NAME$, $CLASS_NAME$Builder> { $CLASS_NAME$._(); factory $CLASS_NAME$([void Function($CLASS_NAME$Builder) updates]) = _$$$CLASS_NAME$; } ``` -------------------------------- ### Custom Builder Class with Defaults Source: https://context7.com/google/built_value.dart/llms.txt Implement an explicit builder class when default field values are needed. The builder must implement `Builder`, use regular mutable fields, and provide a constructor and factory matching generated naming conventions. ```dart import 'package:built_value/built_value.dart'; part 'settings.g.dart'; abstract class Settings implements Built { bool get darkMode; int get fontSize; String get language; factory Settings([void Function(SettingsBuilder) updates]) = _$Settings; Settings._(); } // Explicit builder with default values for every field abstract class SettingsBuilder implements Builder { // Defaults set directly as field initializers bool darkMode = false; int fontSize = 14; String language = 'en'; factory SettingsBuilder() = _$SettingsBuilder; SettingsBuilder._(); } void main() { // Created with all defaults final defaultSettings = Settings(); print(defaultSettings.darkMode); // false print(defaultSettings.fontSize); // 14 print(defaultSettings.language); // en // Override only what you need final custom = Settings((b) => b..darkMode = true..fontSize = 18); print(custom.language); // en (default preserved) } ``` -------------------------------- ### Implement Builder Hooks with @BuiltValueHook Source: https://context7.com/google/built_value.dart/llms.txt Register static methods on the value class using @BuiltValueHook to execute logic when a builder is initialized (for defaults) or before build() is called (for finalization/validation). ```dart import 'package:built_value/built_value.dart'; import 'package:built_collection/built_collection.dart'; part 'order.g.dart'; abstract class Order implements Built { String get id; BuiltList get items; DateTime get createdAt; String get status; // Called when builder is first created — sets defaults @BuiltValueHook(initializeBuilder: true) static void _setDefaults(OrderBuilder b) { b ..status = 'pending' ..createdAt = DateTime.now().toUtc(); } // Called just before build() — validates and normalizes data @BuiltValueHook(finalizeBuilder: true) static void _finalize(OrderBuilder b) { // Sort items alphabetically before the value is created b.items.sort(); if (b.items.isEmpty) throw ArgumentError('Order must have at least one item'); } Order._(); factory Order([void Function(OrderBuilder) updates]) = _$Order; } void main() { final order = Order((b) => b ..id = 'ORD-001' ..items = ListBuilder(['banana', 'apple', 'cherry'])); print(order.status); // pending print(order.items); // [apple, banana, cherry] — sorted by finalizer } ``` -------------------------------- ### Perform Validation in Constructor Source: https://context7.com/google/built_value.dart/llms.txt Use the private constructor body to perform field invariant checks after all fields are initialized. This is the appropriate place for validation logic that should run every time an instance is built. ```dart import 'package:built_value/built_value.dart'; part 'validated_value.g.dart'; abstract class ValidatedValue implements Built { int get anInt; String? get aString; factory ValidatedValue([void Function(ValidatedValueBuilder) updates]) = _$ValidatedValue; // Validation runs every time an instance is built ValidatedValue._() { if (anInt < 0) throw ArgumentError('anInt must be non-negative, got $anInt'); if (anInt == 7) throw StateError('anInt may not be 7'); if (aString != null && aString!.isEmpty) { throw ArgumentError('aString must not be empty if provided'); } } } void main() { // Valid final v = ValidatedValue((b) => b..anInt = 5..aString = 'hello'); print(v.anInt); // 5 // Throws ArgumentError try { ValidatedValue((b) => b..anInt = -1); } on ArgumentError catch (e) { print(e.message); // anInt must be non-negative, got -1 } // Throws StateError try { ValidatedValue((b) => b..anInt = 7); } on StateError catch (e) { print(e.message); // anInt may not be 7 } } ``` -------------------------------- ### Define an Immutable User Data Model with Built Value Source: https://context7.com/google/built_value.dart/llms.txt This Dart code defines an immutable `User` data model using `built_value`. It includes necessary directives, a static serializer, and a factory constructor for creating instances. Ensure you run `build_runner` to generate the corresponding `.g.dart` file. ```dart // Every file with Built types needs: // 1. A `part` directive referencing the .g.dart file // 2. The generated factory: factory MyClass([void Function(MyClassBuilder)]) = _$MyClass; // 3. The private constructor: MyClass._(); // File: lib/models/user.dart library user; // optional but recommended import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; part 'user.g.dart'; // <-- generated file abstract class User implements Built { static Serializer get serializer => _$userSerializer; int get id; String get name; factory User([void Function(UserBuilder) updates]) = _$User; User._(); } ``` -------------------------------- ### Customize Wire Names for Value Classes and Fields Source: https://context7.com/google/built_value.dart/llms.txt Use `@BuiltValue(wireName: ...)` on the class and `@BuiltValueField(wireName: ...)` on fields to match third-party API conventions. Fields marked with `serialize: false` are excluded from serialization. ```dart import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; part 'api_user.g.dart'; // On the wire this type is identified as 'usr', not 'ApiUser' @BuiltValue(wireName: 'usr') abstract class ApiUser implements Built { static Serializer get serializer => _$apiUserSerializer; @BuiltValueField(wireName: 'user_id') int get userId; @BuiltValueField(wireName: 'first_name') String get firstName; @BuiltValueField(wireName: 'last_name') String get lastName; // Field excluded from serialization @BuiltValueField(serialize: false) String get fullName => '$firstName $lastName'; factory ApiUser([void Function(ApiUserBuilder) updates]) = _$ApiUser; ApiUser._(); } // JSON wire format: {"user_id": 1, "first_name": "Jane", "last_name": "Doe"} // Dart usage: void main() { final user = ApiUser((b) => b ..userId = 1 ..firstName = 'Jane' ..lastName = 'Doe'); print(user.fullName); // Jane Doe (not serialized) } ``` -------------------------------- ### Validate a field on instantiation Source: https://github.com/google/built_value.dart/blob/master/README.md Implement validation logic within the private constructor of your value class. This ensures fields meet specific criteria before the object is fully created. ```dart abstract class MyValue { MyValue._() { if (field < 0) { throw ArgumentError(field, 'field', 'Must not be negative.'); } } ``` -------------------------------- ### Using JsonObject for Arbitrary JSON Values Source: https://context7.com/google/built_value.dart/llms.txt Wraps arbitrary JSON values (bool, num, String, List, Map) for use in Built Value fields, providing deep equality and hashCode. Use to pass through JSON blobs alongside typed fields. ```dart import 'package:built_collection/built_collection.dart'; import 'package:built_value/built_value.dart'; import 'package:built_value/json_object.dart'; import 'package:built_value/serializer.dart'; part 'config_entry.g.dart'; abstract class ConfigEntry implements Built { static Serializer get serializer => _$configEntrySerializer; String get key; JsonObject get value; // arbitrary JSON value factory ConfigEntry([void Function(ConfigEntryBuilder) updates]) = _$ConfigEntry; ConfigEntry._(); } void main() { // Wrap different JSON primitives final strObj = JsonObject('hello'); final numObj = JsonObject(42); final boolObj = JsonObject(true); final listObj = JsonObject([1, 2, 3]); final mapObj = JsonObject({'nested': 'map', 'count': 5}); // Type checking and casting print(strObj.isString); // true print(strObj.asString); // hello print(numObj.isNum); // true print(numObj.asNum); // 42 print(listObj.isList); // true print(listObj.asList[1]); // 2 print(mapObj.isMap); // true print(mapObj.asMap['nested']); // map // Use in a built_value final entry = ConfigEntry((b) => b ..key = 'settings' ..value = mapObj); print(entry.key); // settings print(entry.value.asMap); // {nested: map, count: 5} // Deep equality assert(JsonObject([1, 2, 3]) == JsonObject([1, 2, 3])); } ``` -------------------------------- ### Merging Serializers with `Serializers.merge` Source: https://context7.com/google/built_value.dart/llms.txt Combines multiple Serializers instances into one. Useful for modular applications where different packages define their own serializers. Ensure all necessary types are included in the `@SerializersFor` annotations. ```dart import 'package:built_value/serializer.dart'; // Each module declares its own serializers // module_a/serializers.dart @SerializersFor([TypeA, TypeB]) final Serializers moduleASerializers = _$moduleASerializers; // module_b/serializers.dart @SerializersFor([TypeC, TypeD]) final Serializers moduleBSerializers = _$moduleBSerializers; // app-level merging import 'package:myapp/module_a/serializers.dart'; import 'package:myapp/module_b/serializers.dart'; import 'package:built_value/standard_json_plugin.dart'; final Serializers appSerializers = (Serializers.merge([ moduleASerializers, moduleBSerializers, ]).toBuilder() ..addPlugin(StandardJsonPlugin())) .build(); void main() { // appSerializers can handle TypeA, TypeB, TypeC, TypeD final a = TypeA((b) => b..name = 'example'); final serialized = appSerializers.serializeWith(TypeA.serializer, a); print(serialized); } ``` -------------------------------- ### Define a serializable Person class Source: https://github.com/google/built_value.dart/blob/master/README.md Use `@BuiltValueField` to map JSON keys to Dart member variables. Ensure all necessary imports are included. ```dart import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; import 'package:built_collection/built_collection.dart'; part 'person.g.dart'; abstract class Person implements Built { static Serializer get serializer => _$personSerializer; int get id; int? get age; @BuiltValueField(wireName: 'first_name') String? get firstName; BuiltList get hobbies; Person._(); factory Person([void Function(PersonBuilder) updates]) = _$Person; } ``` -------------------------------- ### Configure Built Value Class with @BuiltValue Source: https://context7.com/google/built_value.dart/llms.txt Use the @BuiltValue annotation to configure class-level settings such as wire names and builder behavior. Set 'generateBuilderOnSetField: true' to add an onSet callback to the builder for change notifications. ```dart import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; part 'config.g.dart'; // 'wireName' changes the JSON type discriminator from 'Config' to 'CFG' // 'generateBuilderOnSetField: true' adds an onSet callback to the builder @BuiltValue(wireName: 'CFG', generateBuilderOnSetField: true) abstract class Config implements Built { static Serializer get serializer => _$configSerializer; String get host; int get port; Config._(); factory Config([void Function(ConfigBuilder) updates]) = _$Config; } void main() { final builder = ConfigBuilder(); // Attach a listener that fires whenever any field is set builder.onSet = () => print('Builder was modified'); builder.host = 'localhost'; // prints: Builder was modified builder.port = 8080; // prints: Builder was modified final config = builder.build(); print(config); // Config { host=localhost, port=8080, } } ``` -------------------------------- ### Process a field before instantiation Source: https://github.com/google/built_value.dart/blob/master/README.md Use the `@BuiltValueHook(finalizeBuilder: true)` annotation to run custom logic, such as sorting a list, immediately before the builder is finalized and the value is created. ```dart @BuiltValueHook(finalizeBuilder: true) static void _sortItems(MyValueBuilder b) => b..items.sort(); ``` -------------------------------- ### Generic Value Types with Built Value Source: https://context7.com/google/built_value.dart/llms.txt Implement generic value types like `Result`, `Range`, and `Page` to support parameterized data structures. These generics are fully supported by the serializer. ```dart import 'package:built_collection/built_collection.dart'; import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; part 'result.g.dart'; // Generic value type — T can be any serializable type abstract class Result implements Built, ResultBuilder> { static Serializer get serializer => _$resultSerializer; bool get success; T? get data; String? get error; factory Result([void Function(ResultBuilder) updates]) = _$Result; Result._(); } // Bounded generic — T must extend num abstract class Range implements Built, RangeBuilder> { static Serializer get serializer => _$rangeSerializer; T get min; T get max; factory Range([void Function(RangeBuilder) updates]) = _$Range; Range._(); } // Generic with built_collection field abstract class Page implements Built, PageBuilder> { static Serializer get serializer => _$pageSerializer; BuiltList get items; int get totalCount; int get pageNumber; factory Page([void Function(PageBuilder) updates]) = _$Page; Page._(); } void main() { final success = Result((b) => b..success = true..data = 'hello'); final failure = Result((b) => b..success = false..error = 'Not found'); final range = Range((b) => b..min = 0.0..max = 100.0); final page = Page((b) => b ..items = ListBuilder(['a', 'b', 'c']) ..totalCount = 3 ..pageNumber = 1); print(success.data); // hello print(failure.error); // Not found print(range.min); // 0.0 print(page.items.length); // 3 } ``` -------------------------------- ### Polymorphic Animal Types with Built Value Source: https://context7.com/google/built_value.dart/llms.txt Define a non-instantiable base interface `Animal` that other `Built` types like `Cat` and `Dog` can implement. This allows for rebuilding instances through the base interface type. ```dart import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; part 'animal.g.dart'; // Non-instantiable: no constructor or concrete impl generated @BuiltValue(instantiable: false) abstract class Animal { int get legs; String get sound; Animal rebuild(void Function(AnimalBuilder) updates); AnimalBuilder toBuilder(); } abstract class Cat extends Object implements Animal, Built { static Serializer get serializer => _$catSerializer; @override int get legs; @override String get sound; bool get hasTail; factory Cat([void Function(CatBuilder) updates]) = _$Cat; Cat._(); } abstract class Dog extends Object implements Animal, Built { static Serializer get serializer => _$dogSerializer; @override int get legs; @override String get sound; String get breed; factory Dog([void Function(DogBuilder) updates]) = _$Dog; Dog._(); } void main() { final animals = [ Cat((b) => b..legs = 4..sound = 'meow'..hasTail = true), Dog((b) => b..legs = 4..sound = 'woof'..breed = 'Labrador'), ]; // Rebuild through the interface type — leg count incremented for all animals final louder = animals .map((a) => a.rebuild((b) => b.legs = b.legs! + 0)) .toList(); for (final animal in louder) { print('${animal.runtimeType}: ${animal.sound}'); // Cat: meow // Dog: woof } } ``` -------------------------------- ### Async Deserialization for Large Lists Source: https://context7.com/google/built_value.dart/llms.txt Deserializes large BuiltList payloads asynchronously using an async generator, yielding items as a Stream. This prevents blocking the event loop when processing large arrays from network responses. ```dart import 'package:built_value/async_serializer.dart'; import 'package:built_value/serializer.dart'; import 'package:myapp/serializers.dart'; import 'package:myapp/models/user.dart'; Future main() async { // Simulates a large serialized list from a network response final serializedList = [ ['User', 'id', 1, 'name', 'Alice'], ['User', 'id', 2, 'name', 'Bob'], ['User', 'id', 3, 'name', 'Carol'], ]; final asyncDeserializer = BuiltListAsyncDeserializer(); // Process items as a stream — avoids blocking the event loop final stream = asyncDeserializer.deserialize( serializers, serializedList, specifiedType: const FullType(User), ); await for (final item in stream) { final user = item as User; print('Received user: ${user.name}'); // Alice, Bob, Carol } } ``` -------------------------------- ### Memoized Getters with @memoized Source: https://context7.com/google/built_value.dart/llms.txt Use @memoized for expensive computed getters on value types. They are lazily evaluated and cached per instance, ensuring computation only happens once. ```dart import 'package:built_value/built_value.dart'; import 'package:built_collection/built_collection.dart'; part 'document.g.dart'; abstract class Document implements Built { BuiltList get words; // Computed once on first access, then cached @memoized int get wordCount => words.length; @memoized String get summary => words.take(10).join(' ') + (words.length > 10 ? '...' : ''); @memoized BuiltMap get wordFrequency { final freq = {}; for (final word in words) { freq[word] = (freq[word] ?? 0) + 1; } return BuiltMap(freq); } Document._(); factory Document([void Function(DocumentBuilder) updates]) = _$Document; } void main() { final doc = Document((b) => b ..words = ListBuilder(['dart', 'is', 'great', 'dart', 'rocks'])); print(doc.wordCount); // 5 print(doc.summary); // dart is great dart rocks print(doc.wordFrequency['dart']); // 2 // All three getters computed once and cached — subsequent calls return cached values } ``` -------------------------------- ### EnumClass Wire Name Customization Source: https://context7.com/google/built_value.dart/llms.txt Customize JSON serialization wire names for EnumClass and its constants using @BuiltValueEnum and @BuiltValueEnumConst. Supports string wire names and integer wire numbers. ```dart import 'package:built_collection/built_collection.dart'; import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; part 'status.g.dart'; // Class wire name changes 'Status' -> 'ST' in the type discriminator @BuiltValueEnum(wireName: 'ST') class Status extends EnumClass { static Serializer get serializer => _$statusSerializer; // String wire name override @BuiltValueEnumConst(wireName: 'ACT') static const Status active = _$active; // Integer wire number — serializes to 0 instead of 'inactive' @BuiltValueEnumConst(wireNumber: 0) static const Status inactive = _$inactive; @BuiltValueEnumConst(wireNumber: 1) static const Status pending = _$pending; const Status._(String name) : super(name); static BuiltSet get values => _$statusValues; static Status valueOf(String name) => _$statusValueOf(name); } // JSON: active -> "ACT", inactive -> 0, pending -> 1 ``` -------------------------------- ### Define Value Type with Built Collections Source: https://context7.com/google/built_value.dart/llms.txt Use `BuiltList`, `BuiltSet`, `BuiltMap`, and `BuiltListMultimap` for collection fields in value types. The generated builder provides mutable builder types for these fields. ```dart import 'package:built_collection/built_collection.dart'; import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; part 'catalog.g.dart'; abstract class Catalog implements Built { static Serializer get serializer => _$catalogSerializer; BuiltList get tags; BuiltSet get categories; BuiltMap get inventory; // String -> int BuiltListMultimap get aliases; // one key -> many values factory Catalog([void Function(CatalogBuilder) updates]) = _$Catalog; Catalog._(); } void main() { final catalog = Catalog((b) => b ..tags = ListBuilder(['sale', 'new', 'featured']) ..categories = SetBuilder(['electronics', 'books']) ..inventory = MapBuilder({'widget-A': 50, 'widget-B': 12}) ..aliases = ListMultimapBuilder({ 'phone': ['mobile', 'cell', 'handset'], })); print(catalog.tags); // [sale, new, featured] print(catalog.categories.contains('books')); // true print(catalog.inventory['widget-A']); // 50 // Rebuild with modified collection final updated = catalog.rebuild((b) => b ..tags.add('clearance') ..inventory['widget-C'] = 100); print(updated.tags); // [sale, new, featured, clearance] print(updated.inventory.length); // 3 } ``` -------------------------------- ### Set Default Field Value in Built Value Source: https://github.com/google/built_value.dart/blob/master/README.md Use the @BuiltValueHook with initializeBuilder: true to set default values for fields when a builder is created. This hook runs automatically. ```dart abstract class MyValue { @BuiltValueHook(initializeBuilder: true) static void _setDefaults(MyValueBuilder b) => b ..name = 'defaultName' ..count = 0; ``` -------------------------------- ### Type-Safe EnumClass with built_value Source: https://context7.com/google/built_value.dart/llms.txt EnumClass provides type-safe enums with serialization support. Constants are declared as static const fields. Use valueOf to look up by name, and it supports a fallback for unknown values. ```dart import 'package:built_collection/built_collection.dart'; import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; part 'color.g.dart'; class Color extends EnumClass { static Serializer get serializer => _$colorSerializer; static const Color red = _$red; static const Color green = _$green; static const Color blue = _$blue; // Optional: use a different JSON wire name @BuiltValueEnumConst(wireName: 'UNKNOWN') @BuiltValueEnumConst(fallback: true) // returned for unrecognized values static const Color unknown = _$unknown; const Color._(String name) : super(name); static BuiltSet get values => _$colorValues; static Color valueOf(String name) => _$colorValueOf(name); } void main() { // All enum constants have names and toString print(Color.red); // red print(Color.red.name); // red // Switch works exactly as with Dart enums final c = Color.green; switch (c) { case Color.red: print('stop'); case Color.green: print('go'); // prints: go case Color.blue: print('sky'); default: print('unknown'); } // Iterate all values for (final color in Color.values) { print(color); // red, green, blue, unknown } // Look up by name final fromName = Color.valueOf('blue'); assert(fromName == Color.blue); // Fallback for unknown names final fallback = Color.valueOf('purple'); // returns Color.unknown (not throw) assert(fallback == Color.unknown); } ``` -------------------------------- ### Control Field Serialization with @BuiltValueField Source: https://context7.com/google/built_value.dart/llms.txt Use the `@BuiltValueField` annotation to customize how fields are serialized or compared. It can map Dart field names to different JSON wire names, exclude fields from comparison (`operator==`, `hashCode`), or exclude them from serialization entirely. ```dart import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; part 'api_response.g.dart'; abstract class ApiResponse implements Built { static Serializer get serializer => _$apiResponseSerializer; // Map Dart field name 'createdAt' to JSON key 'created_at' @BuiltValueField(wireName: 'created_at') DateTime get createdAt; // Exclude from operator== and hashCode (e.g., cache timestamps) @BuiltValueField(compare: false) DateTime? get lastFetched; // Exclude from serialization entirely (computed/transient field) @BuiltValueField(serialize: false) String? get displayLabel; ApiResponse._(); factory ApiResponse([void Function(ApiResponseBuilder) updates]) = _$ApiResponse; } // Usage: JSON {"created_at": "2024-01-15T10:00:00Z"} maps to createdAt getter // Two ApiResponse instances with different lastFetched but same createdAt are equal. ``` -------------------------------- ### Declare Immutable Value Type with Built Source: https://context7.com/google/built_value.dart/llms.txt Define an immutable value type by implementing the `Built` interface. Ensure abstract getters for fields and a private constructor. The generator produces `operator==`, `hashCode`, `toString`, and a `Builder` class. Requires `built_value` and `built_collection` dependencies. ```dart // pubspec.yaml dependencies: // built_value: ^8.12.6 // built_collection: ^5.0.0 // dev_dependencies: // built_value_generator: ^8.12.6 // build_runner: ^2.0.0 import 'package:built_collection/built_collection.dart'; import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; part 'person.g.dart'; abstract class Person implements Built { // Required for serialization static Serializer get serializer => _$personSerializer; int get id; String get firstName; int? get age; // nullable field BuiltList get hobbies; // immutable list from built_collection Person._(); factory Person([void Function(PersonBuilder) updates]) = _$Person; } void main() { // Create an instance final person = Person((b) => b ..id = 1 ..firstName = 'Alice' ..age = 30 ..hobbies = ListBuilder(['reading', 'coding'])); // All value types auto-implement operator==, hashCode, toString print(person); // Person { // id=1, // firstName=Alice, // age=30, // hobbies=[reading, coding], // } // Rebuild creates a new instance with updated fields final updated = person.rebuild((b) => b..age = 31); assert(person != updated); assert(person.id == updated.id); // Convert to builder for multi-step mutation final builder = person.toBuilder(); builder.firstName = 'Alicia'; builder.hobbies.add('hiking'); final renamed = builder.build(); print(renamed.hobbies); // [reading, coding, hiking] } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.