Added pretty_logging and json_serializer
This commit is contained in:
parent
67a81e4442
commit
ee3c10fa53
35 changed files with 1066 additions and 9 deletions
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
4
packages/json_serializer/.travis.yml
Normal file
4
packages/json_serializer/.travis.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
language: dart
|
||||
dart:
|
||||
- dev
|
||||
- stable
|
12
packages/json_serializer/AUTHORS.md
Normal file
12
packages/json_serializer/AUTHORS.md
Normal 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.
|
40
packages/json_serializer/CHANGELOG.md
Normal file
40
packages/json_serializer/CHANGELOG.md
Normal 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.
|
29
packages/json_serializer/LICENSE
Normal file
29
packages/json_serializer/LICENSE
Normal 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.
|
107
packages/json_serializer/README.md
Normal file
107
packages/json_serializer/README.md
Normal 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.
|
1
packages/json_serializer/analysis_options.yaml
Normal file
1
packages/json_serializer/analysis_options.yaml
Normal file
|
@ -0,0 +1 @@
|
|||
include: package:lints/recommended.yaml
|
18
packages/json_serializer/example/main.dart
Normal file
18
packages/json_serializer/example/main.dart
Normal 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")));
|
||||
}
|
18
packages/json_serializer/lib/belatuk_json_serializer.dart
Normal file
18
packages/json_serializer/lib/belatuk_json_serializer.dart
Normal 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');
|
44
packages/json_serializer/lib/src/deserialize.dart
Normal file
44
packages/json_serializer/lib/src/deserialize.dart
Normal 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;
|
||||
}
|
||||
}
|
188
packages/json_serializer/lib/src/reflection.dart
Normal file
188
packages/json_serializer/lib/src/reflection.dart
Normal 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;
|
||||
}
|
36
packages/json_serializer/lib/src/serialize.dart
Normal file
36
packages/json_serializer/lib/src/serialize.dart
Normal 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;
|
||||
}
|
5
packages/json_serializer/lib/src/util.dart
Normal file
5
packages/json_serializer/lib/src/util.dart
Normal 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;
|
||||
}
|
25
packages/json_serializer/lib/src/validation.dart
Normal file
25
packages/json_serializer/lib/src/validation.dart
Normal 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);
|
||||
}
|
13
packages/json_serializer/pubspec.yaml
Normal file
13
packages/json_serializer/pubspec.yaml
Normal 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
|
115
packages/json_serializer/test/deserialization_test.dart
Normal file
115
packages/json_serializer/test/deserialization_test.dart
Normal 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'));
|
||||
}
|
133
packages/json_serializer/test/serialization_test.dart
Normal file
133
packages/json_serializer/test/serialization_test.dart
Normal 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);
|
||||
}
|
51
packages/json_serializer/test/shared.dart
Normal file
51
packages/json_serializer/test/shared.dart
Normal 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 {}
|
32
packages/json_serializer/test/to_json_test.dart
Normal file
32
packages/json_serializer/test/to_json_test.dart
Normal 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};
|
||||
}
|
|
@ -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)
|
||||
|
||||
|
|
12
packages/pretty_logging/AUTHORS.md
Normal file
12
packages/pretty_logging/AUTHORS.md
Normal 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.
|
31
packages/pretty_logging/CHANGELOG.md
Normal file
31
packages/pretty_logging/CHANGELOG.md
Normal 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.
|
29
packages/pretty_logging/LICENSE
Normal file
29
packages/pretty_logging/LICENSE
Normal 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.
|
41
packages/pretty_logging/README.md
Normal file
41
packages/pretty_logging/README.md
Normal 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);
|
||||
```
|
1
packages/pretty_logging/analysis_options.yaml
Normal file
1
packages/pretty_logging/analysis_options.yaml
Normal file
|
@ -0,0 +1 @@
|
|||
include: package:lints/recommended.yaml
|
11
packages/pretty_logging/example/main.dart
Normal file
11
packages/pretty_logging/example/main.dart
Normal 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);
|
||||
}
|
50
packages/pretty_logging/lib/belatuk_pretty_logging.dart
Normal file
50
packages/pretty_logging/lib/belatuk_pretty_logging.dart
Normal 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;
|
||||
}
|
11
packages/pretty_logging/pubspec.yaml
Normal file
11
packages/pretty_logging/pubspec.yaml
Normal 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
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in a new issue