simc / crimson Goto Github PK
View Code? Open in Web Editor NEWFast, efficient and easy-to-use JSON parser and serializer for Dart.
License: Apache License 2.0
Fast, efficient and easy-to-use JSON parser and serializer for Dart.
License: Apache License 2.0
Originally posted by Reprevise December 31, 2022
I have a class like this:
class ApiResponse<T> extends Equatable {
final List<CustomError>? errors;
final T? data;
const ApiResponse({
this.errors,
this.data,
});
T get dataOrThrow => data ?? (throw error!);
CustomError? get error {
// ...
}
factory ApiResponse.fromJson(
Map<String, dynamic> map,
T Function(Map<String, dynamic> json) create,
) {
return ApiResponse<T>(
errors: map['errors'] != null
? List<CustomError>.from(
map['errors']?.map((x) => CustomError.fromJson(x)),
)
: null,
data: map['data'] != null ? create(map['data']) : null,
);
}
factory ApiResponse.fromJsonList(
Map<String, dynamic> map,
T Function(List<Map<String, dynamic>>) create, {
List<dynamic> Function(Map<String, dynamic> json)? list,
}) {
T? getData() {
if (map['data'] == null) return null;
final items = List<Map?>.from(
list?.call(map['data'] as Map<String, dynamic>) ??
map['data'] as List<dynamic>,
);
return create(
items.whereNotNull().map((e) => e as Map<String, dynamic>).toList(),
);
}
return ApiResponse<T>(
errors: map['errors'] != null
? List<CustomError>.from(
map['errors'].map((x) => CustomError.fromJson(x)),
)
: null,
data: getData(),
);
}
@override
List<Object?> get props => [errors, data];
}
I use it as so:
return ApiResponse.fromJsonList(
response.data as Map<String, dynamic>,
(json) => json.map(MyModel.fromJson).toList(),
list: (json) => List<Map?>.from(json['items']),
).data!;
How can I do this with Crimson?
The README states that the fromJson
factory takes a Uint8List
as does the fromBytes
factory. If that's the case, then what's the difference?
What I believe happened is a copy-paste error as when I try and read a nested Crimson class, Crimson tries to pass a Map<String, dynamic>
to the fromJson method of the other class.
Please confirm, thanks!
EDIT: The README also appears to be missing toJson
as well.
I'm looking for a plan for Dart 3 macro support similar to this library? Yes, I hate build.
I really like the factory constructor syntax from json_serializable, to be able to call Model.fromJson(uint8List)
.
I'm aware this would just be syntactic-sugar with out much value, but could help migrating from json_serializable to crimson, and it could be just optionally.
If there is a factory constructor that returns _$<className>(buffer)
(or some other name convention)
@json
class Model {
// ...
factory Model.fromJson(List<int> buffer) => _$Model(buffer);
}
then generate additional extensions like so:
Model _$Model(List<int> buffer) => ModelExt.fromJson(buffer);
extension ModelExt on Model {
static Model fromJson(List<int> buffer) {
final crimson = Crimson(buffer);
return crimson.readModel();
}
Uint8List toJson() {
final writer = CrimsonWriter();
writer.writeModel(this);
return writer.toBytes();
}
}
extension ModelList on List<Model> {
static List<Model> fromJson(List<int> buffer) {
final crimson = Crimson(buffer);
return crimson.readModelList();
}
Uint8List toJson() {
final writer = CrimsonWriter();
writer.writeModelList(this);
return writer.toBytes();
}
}
then you can call
final Model model = Model.fromJson(singleModelUint8List);
final Uint8List foo = model.toJson();
final List<Model> list = ModelList.fromJson(listUint8List);
final Uint8List bar = list.toJson();
If this is something you want I can create a PR.
Due to varying field naming conventions, Crimson should have support for renaming all fields in a class by providing an enum value to the json annotation with whatever case the fields come in. All that is provided currently is the name
field on the JsonField
annotation. json_serializable
has support for kebab
, screamingSnake
, pascal
, and snake
via its FieldRename
enum. This should also apply to enums as well.
If i use part directive import like this, it is not recognized while running build_runner.
part '../generated/models/message.g.dart';
I want to save markdown text as json file, I first encode the text by base64 and then convert it to json string by this library. But I found that if the markdown file is a little bit more complex, it produces the effect in the picture below.
Even so, the library can still parse the data correctly, I'm not sure if this is a bug or not.
Here is my class code:
@json
class Content {
@jsonIgnore
Id id = Isar.autoIncrement;
String title = "";
Category category = Category();
Book book = Book();
String? detail;
}
Here is the code I used for serialization:
...
final writer = CrimsonWriter();
final contents = await Content.allContent();
ContentBase64Encode(contents);
writer.writeContentOrNullList(contents);
...
Here is the code I used for deserialization:
...
final crimson = Crimson(await file.readAsBytes());
final contents = crimson.readContentOrNullList();
ContentBase64Decode(contents);
...
I know this library is in the very early stages but I think this package combined with freezed (instead of freezed + json_serializable) would be powerful.
P.S: big fan of your libraries
currently to json method is getting error when building with freezed
Would be very helpful if this limitation could be lifted:
Important: You can only use a pointer prefix once in a class. For example, you can't use /user and /user/name in the same class.
The idea of having mutable models is bad from the start and has known limitations and issues.
When encoding any enum field with JsonName annotation, the annotated name is not serialized to output, rather just the enum value.name is used.
If the analysis_options.yaml enforces strict-casts for you project
include: package:flutter_lints/flutter.yaml
analyzer:
language:
strict-casts: true
#
strict-inference: true
strict-raw-types: true
The generated code for assigning a bool will have a invalid_assignment
error
case -6615550055289275125: // hello
hello = read();
break;
` static final Map<String, dynamic> userMeResponse = jsonDecode(''' {
"me": {
"id": "some-id",
"firstName": "erst",
"lastName": "zwei"
}
}''';
`
How to read the Map<String, dynamic> as from Json.
final crimson = Crimson(utf8.encode(userMeResponse));
print (crimson.read());
final xyz = crimson.readXYZ();
Please could you provide a sample where Map<String, dynamic> is being read and consumed by Crimson
crimson_demo % flutter pub get
Because every version of flutter from sdk depends on collection 1.16.0 and analyzer >=5.3.1 depends on collection ^1.17.0, flutter from sdk is incompatible with analyzer >=5.3.1.
And because every version of crimson depends on analyzer ^5.3.1, flutter from sdk is incompatible with crimson.
So, because crimson_demo depends on both flutter from sdk and crimson ^0.0.2, version solving failed.
Running "flutter pub get" in crimson_demo...
pub get failed (1; So, because crimson_demo depends on both flutter from sdk and crimson ^0.0.2, version solving failed.)
It would be nice to be able to disable generating serialization or parsing code as such:
@Json(toJson: false, fromJson: true) // or some other names
class MyModel {
// ...
}
It would also be useful to add a property for disabling the list methods. This should also be configurable from the build.yaml.
Let's say we have a Tweet
class that uses Reply
as a field. This works on non freezed classes
@json
class Tweet {
DateTime? created_at;
String? tweet;
Reply? reply;
}
@json
class Reply {
DateTime? created_at;
String? reply;
}
When I convert this to freezed class I see that generated readTweet
looking for fromJson
methods in Reply
which not exists.
@freezed
class Tweet with _$Tweet {
@json
const factory Tweet({
DateTime? created_at,
String? tweet,
Reply? reply
}) = _Tweet;
}
@freezed
class Reply with _$Reply {
@json
const factory Reply({
DateTime? created_at,
String? reply,
}) = _Reply;
}
// ---- .g ----
extension ReadTweet on Crimson {
Tweet readTweet() {
DateTime? created_at;
String? tweet;
Reply? reply;
loop:
while (true) {
switch (iterObjectHash()) {
case -1:
break loop;
case -3141059728106243719: // created_at
created_at = skipNull() ? null : DateTime.parse(readString());
break;
case -5949187214024354806: // tweet
tweet = readStringOrNull();
break;
case -777431743796252409: // reply
reply = Reply.fromJson(read());
break;
default:
skip();
break;
}
}
...
}
...
}
I'm guessing the red is crimson.
What are the blue and green?
Hi Simon,
I saw that you've implemented Json Pointer(RFC 6901) and I'm just wondering if it's possible to only use the pointer without the serialization?
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.