@@ -28,27 +28,25 @@ To use the package [`generic_reader`][generic_reader] the following steps are re
2828your pubspec.yaml file.
2929
30302 . Register a [ Decoder] [ Decoder ] object for each * user defined*
31- data-type ` T ` that is going to be read.
31+ data-type ` T ` that is going to be read. < br />
3232Note: The following type are supported out-of-the-box and do * not* require a decoder:
3333* ` bool ` , ` double ` , ` int ` , ` num ` ,` String ` , ` Type ` , ` Symbol ` ,
3434* ` List<bool> ` , ` List<double> ` , ` List<int> ` , ` List<num> ` ,
35- ` List<String> ` ,` List<Symbol ` ,` List<Type ` ,
36- * ` Set<bool ` , ` Set<double ` , ` Set<int ` , ` Set<num ` , ` Set<String ` , ` Set<Symbol ` ,
37- ` Set<Type ` ,
38- * ` Iterable<bool ` ,` Iterable<double ` ,` Iterable<int ` ,` Iterable<num ` ,` Iterable<String ` ,
39- ` Iterable<Symbol ` ,` Iterable<Type ` .
35+ ` List<String> ` ,` List<Symbol> ` ,` List<Type> ` ,
36+ * ` Set<bool> ` , ` Set<double> ` , ` Set<int> ` , ` Set<num> ` , ` Set<String> ` , ` Set<Symbol> ` ,
37+ ` Set<Type> ` ,
38+ * ` Iterable<bool> ` ,` Iterable<double> ` ,` Iterable<int> ` ,` Iterable<num> ` ,` Iterable<String> ` ,
39+ ` Iterable<Symbol> ` ,` Iterable<Type> ` .
4040
41413 . Use Dart's static [ ` analyzer ` ] [ analyzer ] to read a library, get
4242the relevant [ ` VariableElement ` ] [ VariableElement ] , and calculate the constant
43- expression represented by a [ ` DartObject ` ] [ DartObject ] using the method [ ` computeConstantValue() ` ] [ computeConstantValue() ] .
43+ expression represented by a [ ` DartObject ` ] [ DartObject ]
44+ using the method [ ` computeConstantValue() ` ] [ computeConstantValue() ] .
4445
45464 . Read the compile-time constant values using the extension method: [ ` read<T> ` ] [ read ] . <br />
4647
47- To read constant of a user-defined type ` U ` , add a suitable ` Decoder<U> ` :
48- ``` Dart
49- Reader.addDecoder<U>(decoder);
50-
51- ```
48+ To read a constant of a user-defined type ` U ` , add a suitable ` Decoder<U `
49+ (see section [ Custom Decoders] ( #custom-decoders ) );
5250
5351 To read a constant representing a * collection* of a * user-defined* type ` U `
5452 use the convenience methods [ ` readList<U> ` ] [ readList ] ,
@@ -60,7 +58,7 @@ expression represented by a [`DartObject`][DartObject] using the method [`comput
60585 . Use the constant values to generate the source-code and complete the building
6159process.
6260
63- ## Decoder
61+ ## Custom Decoders
6462
6563The extension [ ` Reader ` ] [ Reader ] provides a systematic method of
6664retrieving constants of
@@ -69,13 +67,13 @@ arbitrary data-types by allowing users to register `Decoder` objects.
6967` Decoder<T> ` is an abstract
7068parameterized class with a method ` T read<T>(DartObject obj) `
7169that attempt to read a variable of type ` T ` from ` obj ` and return the result.
72- The example below demonstrates how to create a custom decode for the
70+ The example below demonstrates how to create a custom decoder for the
7371sample class ` Annotation ` and register an instance of the decoder with
7472the extension [ ` Reader ` ] [ Reader ] .
7573
7674``` Dart
7775import 'package:generic_reader/generic_reader.dart';
78-
76+ // An annotation with a const constructor
7977class Annotation {
8078 const A({required this.id, required this.names,);
8179 final int id;
@@ -91,16 +89,18 @@ class AnnotationDecoder extends Decoder<Annotation> {
9189 @override
9290 Annotation read(DartObject obj) {
9391 final id = obj.read<int>(fieldName: 'id');
94- final names = obj.readSet< String>(fieldName: 'names');
92+ final names = obj.read<Set< String> >(fieldName: 'names');
9593 return A(id: id, names: names);
9694 }
9795}
98-
99- Read .addDecoder(const AnnotationDecoder());
96+ // Registering the decoder with the reader
97+ Reader .addDecoder(const AnnotationDecoder());
10098```
10199
102- The example below show how to register a decoder for a Dart ` Enum ` and read
103- an instance of the enumeration. In this case, instead of creating a custom
100+ ## Reading an Enumeration
101+
102+ The example below show how to register and read an instance of an enumeration.
103+ In this case, instead of creating a custom
104104decoder class we register an instance of the already defined generic class
105105[ ` EnumDecoder ` ] [ EnumDecoder ] :
106106
@@ -155,46 +155,40 @@ Future<void> main() async {
155155</details >
156156
157157
158- < br />
158+ ## Reading a Nested List
159159
160- The program listed below show how to read a constant of type
160+ The program listed below is available in the folder [ example] [ example ] and
161+ shows how to read a constant of type
161162` List<List<String>> ` :
162163
163- <details > <summary > Click to show source-code. </summary >
164-
165164``` Dart
166165import 'package:ansi_modifier/ansi_modifier.dart';
167166import 'package:build_test/build_test.dart' show resolveSource;
168167import 'package:generic_reader/generic_reader.dart';
169168
170169/// Demonstrates how to use [Reader] to read a nested list.
171- Future<void> main() async {
172- print('\nReading library: example\n');
173-
174- final lib = await resolveSource(
175- r'''
170+ final libraryString = r'''
176171 library example;
177172
178173 class A {
179174 const A();
180175 final nestedList = List<List<String>> [['a'], ['b']];
181176 }
182- ''',
177+ '''
178+
179+ Future<void> main() async {
180+ print('\nReading library: example\n');
181+
182+ final lib = await resolveSource(libraryString,
183183 (resolver) => resolver.findLibraryByName('example'),
184184 readAllSourcesFromFilesystem: false,
185185 );
186186
187187 if (lib == null) return;
188188
189- final listOfString = 'List<String>'.style(Ansi.green);
190- final listOfListOfString = 'List<List<String>>'.style(Ansi.green);
191-
192- print('\nAdding decoder for $listOfString and $listOfListOfString\n');
193- Reader.addDecoder(const ListDecoder<String>());
189+ print('\nAdding decoder for List<List<String>>\n');
194190 Reader.addDecoder(const ListDecoder<List<String>>());
195191
196- print(Reader.info);
197-
198192 final listObj = lib.classes[0].fields[0].computeConstantValue();
199193 final list1 = listObj?.read<List<List<String>>>();
200194 final list2 = listObj?.read();
@@ -207,12 +201,6 @@ Future<void> main() async {
207201 print('\nlistObj.readList<$listOfString>(): $list3\n');
208202}
209203```
210-
211- </details >
212-
213-
214- <br />
215-
216204The program above produces the following terminal output:
217205
218206
@@ -228,14 +216,7 @@ Reading library: example
228216 1s _ResolveSourceBuilder<LibraryElement?> on 5 inputs: 5 no-op
229217 Built with build_runner in 1s; wrote 0 outputs.
230218
231- Adding decoder for List<String> and List<List<String>>
232-
233-
234- Reader:
235- Decodable types: [bool, double, int, num, String, Symbol, Type,
236- List<bool>, ..., Iterable<Type>, List<List<String>>]
237- Resolved types: {}
238-
219+ Adding decoder for List<List<String>>
239220
240221listObj.read<List<List<String>>>: [[a], [b]]
241222
@@ -246,11 +227,15 @@ listObj.readList<List<String>>(): [[a], [b]]
246227```
247228</details >
248229
230+
249231## Limitations
250232
251- 1 ) Constants retrievable with [ ` Reader ` ] [ Reader ] must have
252- a built-in Dart type, a type made available by depending on
253- a package, or a type defined in the file being read.
233+ 1 ) When using the type ` dynamic ` the static type of the [ DartObject] [ DartObject ]
234+ is used to determine the correct type of the runtime object. If a suitable
235+ decoder is registered with the [ Reader] [ Reader ] on can omit the type parameter
236+ when using e.g. [ ` read ` ] [ read ] . For example, the variable ` list2 ` in section
237+ [ Reading a Nested List] ( #reading-a-nested-list ) is calculated using
238+ [ read] [ read ] .
254239
2552402 ) Defining decoder functions for each data-type has its obvious limitiations when it comes to * generic types* .
256241In practice, however, generic classes are often designed in such a manner
0 commit comments