json_coder 1.0.1 copy "json_coder: ^1.0.1" to clipboard
json_coder: ^1.0.1 copied to clipboard

A lightweight & flexible JSON parser for encoding and decoding data in Dart & Flutter applications.

example/example.dart

// ignore_for_file: avoid_redundant_argument_values

import 'package:json_coder/src/parsers/bool_parser.dart';
import 'package:json_coder/src/parsers/double_parser.dart';
import 'package:json_coder/src/parsers/int_parser.dart';
import 'package:json_coder/src/parsers/list_parser.dart';
import 'package:json_coder/src/parsers/map_parser.dart';
import 'package:json_coder/src/parsers/nullable_int_parser.dart';
import 'package:json_coder/src/parsers/nullable_list_parser.dart';
import 'package:json_coder/src/parsers/nullable_map_parser.dart';
import 'package:json_coder/src/parsers/nullable_string_parser.dart';
import 'package:json_coder/src/parsers/string_parser.dart';
import 'package:json_coder/src/registry/json_parser_registry.dart';
import 'package:json_coder/src/types/json_types.dart';
import 'package:parser_core/parser_core.dart';

class User {
  final int id;
  final String name;
  final String? nickname;

  User({required this.id, required this.name, this.nickname});

  @override
  String toString() => 'User{id: $id, name: $name, nickname: $nickname}';
}

class UserParser implements Parser<User, Json> {
  const UserParser();

  @override
  User decode(Json encoded) {
    final map = encoded! as JsonMap;

    return User(
      id: map['id']! as int,
      name: map['name']! as String,
      nickname: map['nickname'] as String?,
    );
  }

  @override
  Json encode(User value) => {
        'id': value.id,
        'name': value.name,
        'nickname': value.nickname,
      };
}

void main() {
  demoPrimitives();
  demoNullablePrimitives();
  demoNullableCollections();
  demoComplexNested();
  demoParserRegistry();
}

/// Primitives: bool, int, double, String — non-nullable.
void demoPrimitives() {
  print(const BoolParser().decode(const BoolParser().encode(true)));
  print(const IntParser().decode(const IntParser().encode(42)));
  print(const DoubleParser().decode(const DoubleParser().encode(3.14)));
  print(const StringParser().decode(const StringParser().encode('hello')));
}

/// Nullable primitives and nullable list/map wrappers.
void demoNullablePrimitives() {
  // int? — null round-trip
  const intParser = NullableIntParser();
  print(intParser.decode(intParser.encode(null))); // null
  print(intParser.decode(intParser.encode(7))); // 7

  // String? — null round-trip
  const stringParser = NullableStringParser();
  print(stringParser.decode(stringParser.encode(null))); // null
  print(stringParser.decode(stringParser.encode('hi'))); // hi
}

/// Nullable collections: List<T?>?, Map<K, V?>?.
void demoNullableCollections() {
  // List<int?>  — list present, some items null
  const listParser = ListParser(NullableIntParser());
  final list = [1, null, 3];
  print(listParser.decode(listParser.encode(list))); // [1, null, 3]

  // List<int>?  — list itself may be null
  const nullableListParser = NullableListParser(IntParser());
  print(nullableListParser.decode(nullableListParser.encode(null))); // null
  print(nullableListParser.decode(nullableListParser.encode([1, 2]))); // [1, 2]

  // Map<String, int?>  — values may be null
  const mapParser = MapParser(
    keyParser: StringParser(),
    valueParser: NullableIntParser(),
  );
  final map = {'a': 1, 'b': null, 'c': 3};
  print(mapParser.decode(mapParser.encode(map))); // {a: 1, b: null, c: 3}

  // Map<String, int>?  — map itself may be null
  const nullableMapParser = NullableMapParser(
    keyParser: StringParser(),
    valueParser: IntParser(),
  );
  print(nullableMapParser.decode(nullableMapParser.encode(null))); // null
  print(nullableMapParser.decode(nullableMapParser.encode({'x': 9}))); // {x: 9}
}

/// Complex nested: List<Map<String, List<User?>>>.
/// Demonstrates composing parsers arbitrarily, including nullable item lists.
void demoComplexNested() {
  const complexParser = ListParser(
    MapParser(
      keyParser: StringParser(),
      valueParser: ListParser(UserParser()),
    ),
  );

  final data = [
    {
      'admins': [User(id: 1, name: 'John', nickname: 'jj')],
      'guests': [User(id: 2, name: 'Alice', nickname: null)],
    },
  ];

  final encoded = complexParser.encode(data);
  final decoded = complexParser.decode(encoded);

  print('Encoded: $encoded');
  print('Decoded: $decoded');
}

/// Registry: custom parsers registered alongside built-ins,
/// including nullable User variant.
void demoParserRegistry() {
  const userParser = UserParser();

  final registry = JsonParserRegistry.withKnownParsers()..addParser(userParser);

  final user = User(id: 1, name: 'John', nickname: null);

  // Encode/decode via registry lookup
  final encoded = registry.getParser<User>()?.encode(user);
  final decoded = registry.getParser<User>()?.decode(encoded);
  print('Registry User: $decoded');

  // Built-in nullable list from registry
  final scores = [10, null, 30];
  final encodedScores = registry.getParser<List<int?>>()?.encode(scores);
  final decodedScores = registry.getParser<List<int?>>()?.decode(encodedScores);
  print('Registry List<int?>: $decodedScores');

  // getRuntimeParser for dynamic dispatch
  final animals = [user];
  final encodedAnimals = animals
      .map((a) => registry.getRuntimeParser(a.runtimeType)?.encode(a))
      .toList();
  print('Runtime dispatch: $encodedAnimals');
}
0
likes
160
points
7
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A lightweight & flexible JSON parser for encoding and decoding data in Dart & Flutter applications.

Homepage
Repository (GitHub)
View/report issues

License

BSD-3-Clause (license)

Dependencies

parser_core

More

Packages that depend on json_coder