Added pretty_logging and json_serializer

This commit is contained in:
thomashii 2021-09-16 11:23:05 +08:00
parent 67a81e4442
commit ee3c10fa53
35 changed files with 1066 additions and 9 deletions

View file

@ -1,6 +1,6 @@
# Belatuk Body Parser
[![version](https://img.shields.io/badge/pub-v3.0.1-brightgreen)](https://pub.dev/packages/belatuk_body_parser)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/belatuk_body_parser?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/body_parser/LICENSE)

View file

@ -1,6 +1,6 @@
# Belatuk Code Buffer
[![version](https://img.shields.io/badge/pub-v3.0.2-brightgreen)](https://pub.dev/packages/belatuk_code_buffer)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/belatuk_code_buffer?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/code_buffer/LICENSE)

View file

@ -1,6 +1,6 @@
# Belatuk Combinator
[![version](https://img.shields.io/badge/pub-v3.0.1-brightgreen)](https://pub.dev/packages/belatuk_combinator)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/belatuk_combinator?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/combinator/LICENSE)

View file

@ -1,6 +1,6 @@
# Betaluk Html Builder
[![version](https://img.shields.io/badge/pub-v3.0.2-brightgreen)](https://pub.dev/packages/belatuk_html_builder)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/belatuk_html_builder?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/html_builder/LICENSE)

View file

@ -0,0 +1,4 @@
language: dart
dart:
- dev
- stable

View file

@ -0,0 +1,12 @@
Primary Authors
===============
* __[Thomas Hii](dukefirehawk.apps@gmail.com)__
Thomas is the current maintainer of the code base. He has refactored and migrated the
code base to support NNBD.
* __[Tobe O](thosakwe@gmail.com)__
Tobe has written much of the original code prior to NNBD migration. He has moved on and
is no longer involved with the project.

View file

@ -0,0 +1,40 @@
# Change Log
## 5.0.0
* Added `lints` linter
* Removed deprecated parameters
* Published as `belatuk_json_serializer` package
## 4.0.3
* Fixed static analysis errors
## 4.0.2
* Updated pubspec description
* Fixed static analysis errors
## 4.0.1
* Added example
* Updated README
## 4.0.0
* Migrated to support Dart SDK 2.12.x NNBD
## 3.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
## 2.0.0-beta+3
* Long-needed updates, ensured Dart 2 compatibility, fixed DDC breakages.
* Patches for reflection bugs with typing.
## 2.0.0-beta+2
* This version breaks in certain Dart versions (likely anything *after* `2.0.0-dev.59.0`)
until <https://github.com/dart-lang/sdk/issues/33594> is resolved.
* Removes the reference to `Schema` class.

View file

@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2021, dukefirehawk.com
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,107 @@
# Belatuk JSON Serializer
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/json_serializer?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/json_serializer/LICENSE)
**Replacement of `package:json_god` with breaking changes to support NNBD.**
The ***new and improved*** definitive solution for JSON in Dart. It supports synchronously transform an object into a JSON string and also deserialize a JSON string back into an instance of any type.
## Installation
dependencies:
belatuk_json_serializer: ^5.0.0
## Usage
It is recommended to import the library under an alias, i.e., `jsonSerializer`.
```dart
import 'package:belatuk_json_serialization/belatuk_json_serialization.dart' as jsonSerializer;
```
## Serializing JSON
Simply call `jsonSerializer.serialize(x)` to synchronously transform an object into a JSON
string.
```dart
Map map = {"foo": "bar", "numbers": [1, 2, {"three": 4}]};
// Output: {"foo":"bar","numbers":[1,2,{"three":4]"}
String json = jsonSerializer.serialize(map);
print(json);
```
You can easily serialize classes, too. Belatuk JSON Serializer also supports classes as members.
```dart
class A {
String foo;
A(this.foo);
}
class B {
late String hello;
late A nested;
B(String hello, String foo) {
this.hello = hello;
this.nested = A(foo);
}
}
main() {
print(jsonSerializer.serialize( B("world", "bar")));
}
// Output: {"hello":"world","nested":{"foo":"bar"}}
```
If a class has a `toJson` method, it will be called instead.
## Deserializing JSON
Deserialization is equally easy, and is provided through `jsonSerializer.deserialize`.
```dart
Map map = jsonSerializer.deserialize('{"hello":"world"}');
int three = jsonSerializer.deserialize("3");
```
### Deserializing to Classes
Belatuk JSON Serializer lets you deserialize JSON into an instance of any type. Simply pass the type as the second argument to `jsonSerializer.deserialize`.
If the class has a `fromJson` constructor, it will be called instead.
```dart
class Child {
String foo;
}
class Parent {
String hello;
Child child = Child();
}
main() {
Parent parent = jsonSerializer.deserialize('{"hello":"world","child":{"foo":"bar"}}', Parent);
print(parent);
}
```
**Any JSON-deserializable classes must initializable without parameters. If `Foo()` would throw an error, then you can't use Foo with JSON.**
This allows for validation of a sort, as only fields you have declared will be accepted.
```dart
class HasAnInt { int theInt; }
HasAnInt invalid = jsonSerializer.deserialize('["some invalid input"]', HasAnInt);
// Throws an error
```
An exception will be thrown if validation fails.

View file

@ -0,0 +1 @@
include: package:lints/recommended.yaml

View file

@ -0,0 +1,18 @@
import 'package:belatuk_json_serializer/belatuk_json_serializer.dart' as god;
class A {
String foo;
A(this.foo);
}
class B {
String hello;
late A nested;
B(this.hello, String foo) {
nested = A(foo);
}
}
void main() {
print(god.serialize(B("world", "bar")));
}

View file

@ -0,0 +1,18 @@
/// A robust library for JSON serialization and deserialization.
library belatuk_json_serializer;
//import 'package:dart2_constant/convert.dart';
import 'dart:convert';
import 'package:logging/logging.dart';
import 'src/reflection.dart' as reflection;
part 'src/serialize.dart';
part 'src/deserialize.dart';
part 'src/validation.dart';
part 'src/util.dart';
/// Instead, listen to [logger].
//@deprecated
//bool debug = false;
final Logger logger = Logger('belatuk_json_serializer');

View file

@ -0,0 +1,44 @@
part of belatuk_json_serializer;
/// Deserializes a JSON string into a Dart datum.
///
/// You can also provide an output Type to attempt to serialize the JSON into.
deserialize(String json, {Type? outputType}) {
var deserialized = deserializeJson(json, outputType: outputType);
logger.info("Deserialization result: $deserialized");
return deserialized;
}
/// Deserializes JSON into data, without validating it.
deserializeJson(String s, {Type? outputType}) {
logger.info("Deserializing the following JSON: $s");
if (outputType == null) {
logger
.info("No output type was specified, so we are just using json.decode");
return json.decode(s);
} else {
logger.info("Now deserializing to type: $outputType");
return deserializeDatum(json.decode(s), outputType: outputType);
}
}
/// Deserializes some JSON-serializable value into a usable Dart value.
deserializeDatum(value, {Type? outputType}) {
if (outputType != null) {
return reflection.deserialize(value, outputType, deserializeDatum);
} else if (value is List) {
logger.info("Deserializing this List: $value");
return value.map(deserializeDatum).toList();
} else if (value is Map) {
logger.info("Deserializing this Map: $value");
Map result = {};
value.forEach((k, v) {
result[k] = deserializeDatum(v);
});
return result;
} else if (_isPrimitive(value)) {
logger.info("Value $value is a primitive");
return value;
}
}

View file

@ -0,0 +1,188 @@
library belatuk_json_serializer.reflection;
import 'dart:mirrors';
import '../belatuk_json_serializer.dart';
const Symbol hashCodeSymbol = #hashCode;
const Symbol runtimeTypeSymbol = #runtimeType;
typedef Serializer = dynamic Function(dynamic value);
typedef Deserializer = dynamic Function(dynamic value, {Type? outputType});
List<Symbol> _findGetters(ClassMirror classMirror) {
List<Symbol> result = [];
classMirror.instanceMembers
.forEach((Symbol symbol, MethodMirror methodMirror) {
if (methodMirror.isGetter &&
symbol != hashCodeSymbol &&
symbol != runtimeTypeSymbol) {
logger.info("Found getter on instance: $symbol");
result.add(symbol);
}
});
return result;
}
serialize(value, Serializer serializer) {
logger.info("Serializing this value via reflection: $value");
Map result = {};
InstanceMirror instanceMirror = reflect(value);
ClassMirror classMirror = instanceMirror.type;
// Check for toJson
for (Symbol symbol in classMirror.instanceMembers.keys) {
if (symbol == #toJson) {
logger.info("Running toJson...");
var result = instanceMirror.invoke(symbol, []).reflectee;
logger.info("Result of serialization via reflection: $result");
return result;
}
}
for (Symbol symbol in _findGetters(classMirror)) {
String name = MirrorSystem.getName(symbol);
var valueForSymbol = instanceMirror.getField(symbol).reflectee;
try {
result[name] = serializer(valueForSymbol);
logger.info("Set $name to $valueForSymbol");
} catch (e, st) {
logger.severe("Could not set $name to $valueForSymbol", e, st);
}
}
logger.info("Result of serialization via reflection: $result");
return result;
}
deserialize(value, Type outputType, Deserializer deserializer) {
logger.info("About to deserialize $value to a $outputType");
try {
if (value is List) {
List<TypeMirror> typeArguments = reflectType(outputType).typeArguments;
Iterable it;
if (typeArguments.isEmpty) {
it = value.map(deserializer);
} else {
it = value.map((item) =>
deserializer(item, outputType: typeArguments[0].reflectedType));
}
if (typeArguments.isEmpty) return it.toList();
logger.info(
'Casting list elements to ${typeArguments[0].reflectedType} via List.from');
var mirror = reflectType(List, [typeArguments[0].reflectedType]);
if (mirror is ClassMirror) {
var output = mirror.newInstance(#from, [it]).reflectee;
logger.info('Casted list type: ${output.runtimeType}');
return output;
} else {
throw ArgumentError(
'${typeArguments[0].reflectedType} is not a class.');
}
} else if (value is Map) {
return _deserializeFromJsonByReflection(value, deserializer, outputType);
} else {
return deserializer(value);
}
} catch (e, st) {
logger.severe('Deserialization failed.', e, st);
rethrow;
}
}
/// Uses mirrors to deserialize an object.
_deserializeFromJsonByReflection(
data, Deserializer deserializer, Type outputType) {
// Check for fromJson
var typeMirror = reflectType(outputType);
if (typeMirror is! ClassMirror) {
throw ArgumentError('$outputType is not a class.');
}
var type = typeMirror;
var fromJson = Symbol('${MirrorSystem.getName(type.simpleName)}.fromJson');
for (Symbol symbol in type.declarations.keys) {
if (symbol == fromJson) {
var decl = type.declarations[symbol];
if (decl is MethodMirror && decl.isConstructor) {
logger.info("Running fromJson...");
var result = type.newInstance(#fromJson, [data]).reflectee;
logger.info("Result of deserialization via reflection: $result");
return result;
}
}
}
ClassMirror classMirror = type;
InstanceMirror instanceMirror = classMirror.newInstance(Symbol(""), []);
if (classMirror.isSubclassOf(reflectClass(Map))) {
var typeArguments = classMirror.typeArguments;
if (typeArguments.isEmpty ||
classMirror.typeArguments
.every((t) => t == currentMirrorSystem().dynamicType)) {
return data;
} else {
var mapType =
reflectType(Map, typeArguments.map((t) => t.reflectedType).toList())
as ClassMirror;
logger.info('Casting this map $data to Map of [$typeArguments]');
var output = mapType.newInstance(Symbol(''), []).reflectee;
for (var key in data.keys) {
output[key] = data[key];
}
logger.info('Output: $output of type ${output.runtimeType}');
return output;
}
} else {
data.keys.forEach((key) {
try {
logger.info("Now deserializing value for $key");
logger.info("data[\"$key\"] = ${data[key]}");
var deserializedValue = deserializer(data[key]);
logger.info(
"I want to set $key to the following ${deserializedValue.runtimeType}: $deserializedValue");
// Get target type of getter
Symbol searchSymbol = Symbol(key.toString());
Symbol symbolForGetter = classMirror.instanceMembers.keys
.firstWhere((x) => x == searchSymbol);
Type requiredType = classMirror
.instanceMembers[symbolForGetter]!.returnType.reflectedType;
if (data[key].runtimeType != requiredType) {
logger.info("Currently, $key is a ${data[key].runtimeType}.");
logger.info("However, $key must be a $requiredType.");
deserializedValue =
deserializer(deserializedValue, outputType: requiredType);
}
logger.info(
"Final deserialized value for $key: $deserializedValue <${deserializedValue.runtimeType}>");
instanceMirror.setField(Symbol(key.toString()), deserializedValue);
logger.info("Success! $key has been set to $deserializedValue");
} catch (e, st) {
logger.severe('Could not set value for field $key.', e, st);
}
});
}
return instanceMirror.reflectee;
}

View file

@ -0,0 +1,36 @@
part of belatuk_json_serializer;
/// Serializes any arbitrary Dart datum to JSON. Supports schema validation.
String serialize(value) {
var serialized = serializeObject(value);
logger.info('Serialization result: $serialized');
return json.encode(serialized);
}
/// Transforms any Dart datum into a value acceptable to json.encode.
serializeObject(value) {
if (_isPrimitive(value)) {
logger.info("Serializing primitive value: $value");
return value;
} else if (value is DateTime) {
logger.info("Serializing this DateTime: $value");
return value.toIso8601String();
} else if (value is Iterable) {
logger.info("Serializing this Iterable: $value");
return value.map(serializeObject).toList();
} else if (value is Map) {
logger.info("Serializing this Map: $value");
return serializeMap(value);
} else {
return serializeObject(reflection.serialize(value, serializeObject));
}
}
/// Recursively transforms a Map and its children into JSON-serializable data.
Map serializeMap(Map value) {
Map outputMap = {};
value.forEach((key, value) {
outputMap[key] = serializeObject(value);
});
return outputMap;
}

View file

@ -0,0 +1,5 @@
part of belatuk_json_serializer;
bool _isPrimitive(value) {
return value is num || value is bool || value is String || value == null;
}

View file

@ -0,0 +1,25 @@
part of belatuk_json_serializer;
/// Thrown when schema validation fails.
class JsonValidationError implements Exception {
//final Schema schema;
final dynamic invalidData;
final String cause;
const JsonValidationError(
this.cause, this.invalidData); //, Schema this.schema);
}
/// Specifies a schema to validate a class with.
class WithSchema {
final Map schema;
const WithSchema(this.schema);
}
/// Specifies a schema to validate a class with.
class WithSchemaUrl {
final String schemaUrl;
const WithSchemaUrl(this.schemaUrl);
}

View file

@ -0,0 +1,13 @@
name: belatuk_json_serializer
version: 5.0.0
description: Easy JSON to Object serialization and deserialization in Dart.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/json_serializer
environment:
sdk: '>=2.12.0 <3.0.0'
dependencies:
#dart2_constant: ^1.0.0
logging: ^1.0.1
dev_dependencies:
stack_trace: ^1.10.0
test: ^1.17.4
lints: ^1.0.0

View file

@ -0,0 +1,115 @@
import 'package:belatuk_json_serializer/belatuk_json_serializer.dart' as god;
import 'package:test/test.dart';
import 'shared.dart';
main() {
god.logger.onRecord.listen(printRecord);
group('deserialization', () {
test('deserialize primitives', testDeserializationOfPrimitives);
test('deserialize maps', testDeserializationOfMaps);
test('deserialize maps + reflection',
testDeserializationOfMapsWithReflection);
test('deserialize lists + reflection',
testDeserializationOfListsAsWellAsViaReflection);
test('deserialize with schema validation',
testDeserializationWithSchemaValidation);
});
}
testDeserializationOfPrimitives() {
expect(god.deserialize('1'), equals(1));
expect(god.deserialize('1.4'), equals(1.4));
expect(god.deserialize('"Hi!"'), equals("Hi!"));
expect(god.deserialize("true"), equals(true));
expect(god.deserialize("null"), equals(null));
}
testDeserializationOfMaps() {
String simpleJson =
'{"hello":"world", "one": 1, "class": {"hello": "world"}}';
String nestedJson =
'{"foo": {"bar": "baz", "funny": {"how": "life", "seems": 2, "hate": "us sometimes"}}}';
var simple = god.deserialize(simpleJson) as Map;
var nested = god.deserialize(nestedJson) as Map;
expect(simple['hello'], equals('world'));
expect(simple['one'], equals(1));
expect(simple['class']['hello'], equals('world'));
expect(nested['foo']['bar'], equals('baz'));
expect(nested['foo']['funny']['how'], equals('life'));
expect(nested['foo']['funny']['seems'], equals(2));
expect(nested['foo']['funny']['hate'], equals('us sometimes'));
}
class Pokedex {
Map<String, int>? pokemon;
}
testDeserializationOfMapsWithReflection() {
var s = '{"pokemon": {"Bulbasaur": 1, "Deoxys": 382}}';
var pokedex = god.deserialize(s, outputType: Pokedex) as Pokedex;
expect(pokedex.pokemon, hasLength(2));
expect(pokedex.pokemon!['Bulbasaur'], 1);
expect(pokedex.pokemon!['Deoxys'], 382);
}
testDeserializationOfListsAsWellAsViaReflection() {
String json = '''[
{
"hello": "world",
"nested": []
},
{
"hello": "dolly",
"nested": [
{
"bar": "baz"
},
{
"bar": "fight"
}
]
}
]
''';
var list = god.deserialize(json, outputType: (<SampleClass>[]).runtimeType)
as List<SampleClass>;
SampleClass first = list[0];
SampleClass second = list[1];
expect(list.length, equals(2));
expect(first.hello, equals("world"));
expect(first.nested.length, equals(0));
expect(second.hello, equals("dolly"));
expect(second.nested.length, equals(2));
SampleNestedClass firstNested = second.nested[0];
SampleNestedClass secondNested = second.nested[1];
expect(firstNested.bar, equals("baz"));
expect(secondNested.bar, equals("fight"));
}
testDeserializationWithSchemaValidation() async {
String babelRcJson =
'{"presets":["es2015","stage-0"],"plugins":["add-module-exports"]}';
var deserialized =
god.deserialize(babelRcJson, outputType: BabelRc) as BabelRc;
print(deserialized.presets.runtimeType);
expect(deserialized.presets is List, equals(true));
expect(deserialized.presets.length, equals(2));
expect(deserialized.presets[0], equals('es2015'));
expect(deserialized.presets[1], equals('stage-0'));
expect(deserialized.plugins is List, equals(true));
expect(deserialized.plugins.length, equals(1));
expect(deserialized.plugins[0], equals('add-module-exports'));
}

View file

@ -0,0 +1,133 @@
//import 'package:dart2_constant/convert.dart';
import 'dart:convert';
import 'package:belatuk_json_serializer/belatuk_json_serializer.dart' as god;
import 'package:test/test.dart';
import 'shared.dart';
main() {
god.logger.onRecord.listen(printRecord);
group('serialization', () {
test('serialize primitives', testSerializationOfPrimitives);
test('serialize dates', testSerializationOfDates);
test('serialize maps', testSerializationOfMaps);
test('serialize lists', testSerializationOfLists);
test('serialize via reflection', testSerializationViaReflection);
test('serialize with schema validation',
testSerializationWithSchemaValidation);
});
}
testSerializationOfPrimitives() {
expect(god.serialize(1), equals("1"));
expect(god.serialize(1.4), equals("1.4"));
expect(god.serialize("Hi!"), equals('"Hi!"'));
expect(god.serialize(true), equals("true"));
expect(god.serialize(null), equals("null"));
}
testSerializationOfDates() {
DateTime date = DateTime.now();
String s = god.serialize({'date': date});
print(s);
var deserialized = json.decode(s);
expect(deserialized['date'], equals(date.toIso8601String()));
}
testSerializationOfMaps() {
var simple = json.decode(god
.serialize({'hello': 'world', 'one': 1, 'class': SampleClass('world')}));
var nested = json.decode(god.serialize({
'foo': {
'bar': 'baz',
'funny': {'how': 'life', 'seems': 2, 'hate': 'us sometimes'}
}
}));
expect(simple['hello'], equals('world'));
expect(simple['one'], equals(1));
expect(simple['class']['hello'], equals('world'));
expect(nested['foo']['bar'], equals('baz'));
expect(nested['foo']['funny']['how'], equals('life'));
expect(nested['foo']['funny']['seems'], equals(2));
expect(nested['foo']['funny']['hate'], equals('us sometimes'));
}
testSerializationOfLists() {
List pandorasBox = [
1,
"2",
{"num": 3, "four": SampleClass('five')},
SampleClass('six')..nested.add(SampleNestedClass('seven'))
];
String s = god.serialize(pandorasBox);
print(s);
var deserialized = json.decode(s);
expect(deserialized is List, equals(true));
expect(deserialized.length, equals(4));
expect(deserialized[0], equals(1));
expect(deserialized[1], equals("2"));
expect(deserialized[2] is Map, equals(true));
expect(deserialized[2]['num'], equals(3));
expect(deserialized[2]['four'] is Map, equals(true));
expect(deserialized[2]['four']['hello'], equals('five'));
expect(deserialized[3] is Map, equals(true));
expect(deserialized[3]['hello'], equals('six'));
expect(deserialized[3]['nested'] is List, equals(true));
expect(deserialized[3]['nested'].length, equals(1));
expect(deserialized[3]['nested'][0] is Map, equals(true));
expect(deserialized[3]['nested'][0]['bar'], equals('seven'));
}
testSerializationViaReflection() {
SampleClass sample = SampleClass('world');
for (int i = 0; i < 3; i++) {
sample.nested.add(SampleNestedClass('baz'));
}
String s = god.serialize(sample);
print(s);
var deserialized = json.decode(s);
expect(deserialized['hello'], equals('world'));
expect(deserialized['nested'] is List, equals(true));
expect(deserialized['nested'].length == 3, equals(true));
expect(deserialized['nested'][0]['bar'], equals('baz'));
expect(deserialized['nested'][1]['bar'], equals('baz'));
expect(deserialized['nested'][2]['bar'], equals('baz'));
}
testSerializationWithSchemaValidation() async {
BabelRc babelRc =
BabelRc(presets: ['es2015', 'stage-0'], plugins: ['add-module-exports']);
String s = god.serialize(babelRc);
print(s);
var deserialized = json.decode(s);
expect(deserialized['presets'] is List, equals(true));
expect(deserialized['presets'].length, equals(2));
expect(deserialized['presets'][0], equals('es2015'));
expect(deserialized['presets'][1], equals('stage-0'));
expect(deserialized['plugins'] is List, equals(true));
expect(deserialized['plugins'].length, equals(1));
expect(deserialized['plugins'][0], equals('add-module-exports'));
//Map babelRc2 = {'presets': 'Hello, world!'};
String json2 = god.serialize(babelRc);
print(json2);
}

View file

@ -0,0 +1,51 @@
import 'package:logging/logging.dart';
import 'package:belatuk_json_serializer/belatuk_json_serializer.dart';
import 'package:stack_trace/stack_trace.dart';
void printRecord(LogRecord rec) {
print(rec);
if (rec.error != null) print(rec.error);
if (rec.stackTrace != null) print(Chain.forTrace(rec.stackTrace!).terse);
}
class SampleNestedClass {
String? bar;
SampleNestedClass([String? this.bar]);
}
class SampleClass {
String? hello;
List<SampleNestedClass> nested = [];
SampleClass([String? this.hello]);
}
@WithSchemaUrl(
"http://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/babelrc.json")
class BabelRc {
List<String> presets;
List<String> plugins;
BabelRc(
{List<String> this.presets: const [],
List<String> this.plugins: const []});
}
@WithSchema(const {
r"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Validated Sample Class",
"description": "Sample schema for validation via JSON God",
"type": "object",
"hello": const {"description": "A friendly greeting.", "type": "string"},
"nested": const {
"description": "A list of NestedSampleClass items within this instance.",
"type": "array",
"items": const {
"type": "object",
"bar": const {"description": "Filler text", "type": "string"}
}
},
"required": const ["hello", "nested"]
})
class ValidatedSampleClass {}

View file

@ -0,0 +1,32 @@
import 'package:belatuk_json_serializer/belatuk_json_serializer.dart' as god;
import 'package:test/test.dart';
import 'shared.dart';
main() {
god.logger.onRecord.listen(printRecord);
test('fromJson', () {
var foo = god.deserialize('{"bar":"baz"}', outputType: Foo) as Foo;
expect(foo is Foo, true);
expect(foo.text, equals('baz'));
});
test('toJson', () {
var foo = Foo(text: 'baz');
var data = god.serializeObject(foo);
expect(data, equals({'bar': 'baz', 'foo': 'poobaz'}));
});
}
class Foo {
String? text;
String get foo => 'poo$text';
Foo({this.text});
factory Foo.fromJson(Map json) => Foo(text: json['bar'].toString());
Map toJson() => {'bar': text, 'foo': foo};
}

View file

@ -1,6 +1,6 @@
# Belatuk Merge Map
[![version](https://img.shields.io/badge/pub-v3.0.2-brightgreen)](https://pub.dev/packages/belatuk_merge_map)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/belatuk_merge_map?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/merge_map/LICENSE)

View file

@ -0,0 +1,12 @@
Primary Authors
===============
* __[Thomas Hii](dukefirehawk.apps@gmail.com)__
Thomas is the current maintainer of the code base. He has refactored and migrated the
code base to support NNBD.
* __[Tobe O](thosakwe@gmail.com)__
Tobe has written much of the original code prior to NNBD migration. He has moved on and
is no longer involved with the project.

View file

@ -0,0 +1,31 @@
# Change Log
## 4.0.0
* Added `lints` linter
* Removed deprecated parameters
* Published as `belatuk_pretty_logging` package
## 3.0.3
* Updated README
## 3.0.2
* Updated README
## 3.0.1
* Fixed invalid homepage url in pubspec.yaml
## 3.0.0
* Migrated to support Dart SDK 2.12.x NNBD
## 2.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
## 1.0.0
* Initial release.

View file

@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2021, dukefirehawk.com
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,41 @@
# Belatuk Petty Logging
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/belatuk_pretty_logging?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/pretty_logging/LICENSE)
**Replacement of `package:pretty_logging` with breaking changes to support NNBD.**
Standalone helper for colorful logging output, using pkg:io AnsiCode.
## Installation
In your `pubspec.yaml`:
```yaml
dependencies:
belatuk_pretty_logging: ^4.0.0
```
## Usage
Basic usage is very simple:
```dart
myLogger.onRecord.listen(prettyLog);
```
However, you can conditionally pass logic to omit printing an error, provide colors, or to provide a custom print function:
```dart
var pretty = prettyLog(
logColorChooser: (_) => red,
printFunction: stderr.writeln,
omitError: (r) {
var err = r.error;
return err is AngelHttpException && err.statusCode != 500;
},
);
myLogger.onRecord.listen(pretty);
```

View file

@ -0,0 +1 @@
include: package:lints/recommended.yaml

View file

@ -0,0 +1,11 @@
import 'package:logging/logging.dart';
import 'package:belatuk_pretty_logging/belatuk_pretty_logging.dart';
void main() {
Logger.root
..level = Level.ALL
..onRecord.listen(prettyLog)
..info('Hey!')
..finest('Bye!')
..severe('Oops!', StateError('Wrong!'), StackTrace.current);
}

View file

@ -0,0 +1,50 @@
import 'package:logging/logging.dart';
import 'package:io/ansi.dart';
/// Prints the contents of a [LogRecord] with pretty colors.
///
/// By passing [omitError], you can omit printing the error of a given
/// [LogRecord].
///
/// You can also pass a custom [printFunction] or [logColorChooser].
void prettyLog(LogRecord record,
{bool Function(LogRecord)? omitError,
void Function(String)? printFunction,
AnsiCode Function(Level)? logColorChooser}) {
logColorChooser ??= chooseLogColor;
omitError ??= (_) => false;
printFunction ??= print;
var code = logColorChooser(record.level);
if (record.error == null) printFunction(code.wrap(record.toString())!);
if (record.error != null) {
var err = record.error;
if (omitError(record)) return;
printFunction(code.wrap(record.toString() + '\n')!);
printFunction(code.wrap(err.toString())!);
if (record.stackTrace != null) {
printFunction(code.wrap(record.stackTrace.toString())!);
}
}
}
/// Chooses a color based on the logger [level].
AnsiCode chooseLogColor(Level level) {
if (level == Level.SHOUT) {
return backgroundRed;
} else if (level == Level.SEVERE) {
return red;
} else if (level == Level.WARNING) {
return yellow;
} else if (level == Level.INFO) {
return cyan;
} else if (level == Level.CONFIG ||
level == Level.FINE ||
level == Level.FINER ||
level == Level.FINEST) {
return lightGray;
}
return resetAll;
}

View file

@ -0,0 +1,11 @@
name: belatuk_pretty_logging
version: 4.0.0
description: Standalone helper for colorful logging output, using pkg:io AnsiCode.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/pretty_logging
environment:
sdk: '>=2.12.0 <3.0.0'
dependencies:
io: ^1.0.0
logging: ^1.0.1
dev_dependencies:
lints: ^1.0.0

View file

@ -1,6 +1,6 @@
# Belatuk Pub Sub
[![version](https://img.shields.io/badge/pub-v4.0.3-brightgreen)](https://pub.dev/packages/belatuk_pub_sub)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/belatuk_pub_sub?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/pub_sub/LICENSE)

View file

@ -1,6 +1,6 @@
# Belatuk Range Header
[![version](https://img.shields.io/badge/pub-v4.0.1-brightgreen)](https://pub.dev/packages/belatuk_range_header)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/belatuk_range_header?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/range_header/LICENSE)

View file

@ -1,6 +1,6 @@
# Belatuk Symbol Table
[![version](https://img.shields.io/badge/pub-v3.0.1-brightgreen)](https://pub.dev/packages/belatuk_symbol_table)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/belatuk_symbol_table?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/symbol_table/LICENSE)

View file

@ -1,6 +1,6 @@
# User Agent Analyzer
[![version](https://img.shields.io/badge/pub-v3.1.0-brightgreen)](https://pub.dev/packages/user_agent_analyzer)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/user_agent_analyzer?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/user_agent/LICENSE)