generateModel method

void generateModel(
  1. StringBuffer buffer,
  2. Map<String, Object?> iconsMap,
  3. String name, {
  4. Iterable<String> keys = const Iterable<String>.empty(),
})

Generate a model nested from keys.

Implementation

void generateModel(
  final StringBuffer buffer,
  final Map<String, Object?> iconsMap,
  final String name, {
  final Iterable<String> keys = const Iterable<String>.empty(),
}) {
  final String cls = className(name, keys);
  if (keys.isEmpty) {
    String className = cls.decapitalize();
    className = className == cls ? '\$$className' : className;
    buffer
      ..writeDoc('This is a generated structure of an Icon Font.')
      ..writeDoc('')
      ..writeDoc(
        'See: https://pub.dev/packages/generators_lite#icon-fonts-generator',
      )
      ..writeln('const $cls $className = $cls._();')
      ..writeln();
  }

  final Map<String, Object?> map = keys.skip(1).isEmpty && name == baseName
      ? iconsMap
      : iconsMap.getNested(<String>[name, ...keys.skip(1)])!
          as Map<String, Object?>;
  final String parentName = keys.isNotEmpty
      ? className(keys.last, keys.toList()..removeLast())
      : '';
  buffer
    ..writeDoc('The file structure of the `${map['']! as String}` folder.')
    ..writeln('@sealed')
    ..writeln('@immutable')
    ..writeln('class $cls {')

    /// `Constructor`
    ..writeFunction(
      'const ${className(name, keys)}._',
      fields: <String>[if (parentName.isNotEmpty) 'final $parentName _'],
    );

  /// `Fields`
  for (final MapEntry<String, Object?> entry in map.entries) {
    final Object? value = entry.value;
    if (value is Map<String, Object?>) {
      final String key =
          convert ? entry.key.toCamelCase() : entry.key.normalize();
      final String cls = className(entry.key, <String>[...keys, name]);
      final Map<String, Object?> nestedMap =
          map[entry.key]! as Map<String, Object?>;
      final String nestedMapPath = nestedMap['']! as String;
      buffer
        ..writeDoc(
          'The `${posix.basename(nestedMapPath)}` folder in '
          '`${posix.dirname(nestedMapPath)}`.',
          indent: 2,
        )
        ..writeln('$cls get $key => $cls._(this);');
    } else if (value is int) {
      String iconName = posix.basenameWithoutExtension(entry.key);
      iconName = convert ? iconName.toCamelCase() : iconName.normalize();
      final String codePoint = value.toRadixString(16);
      buffer
        ..writeDoc(
          'The [IconData] of the `${posix.basename(entry.key)}` in '
          '`${posix.dirname(entry.key)}`.',
          indent: 2,
        )
        ..writeln('IconData get $iconName => '
            "const IconData(0x$codePoint, fontFamily: '$fontFamily');");
    }
  }
  buffer

    /// `== operator`
    ..writeln()
    ..writeln('@override')
    ..writeFunction(
      'bool operator ==',
      fields: <String>['final Object? other'],
      bodyFields: <String>[
        'identical(this, other) || other is ${className(name, keys)}',
        ...<String>[
          for (final MapEntry<String, Object?> entry in map.entries)
            if (entry.key.isNotEmpty)
              posix.basenameWithoutExtension(entry.key)
        ]
            .map((final _) => convert ? _.toCamelCase() : _.normalize())
            .map((final String key) => 'other.$key == $key')
      ],
      separator: ' && ',
    )

    /// `hashCode`
    ..writeln()
    ..writeln('@override')
    ..writeFunction(
      'int get hashCode',
      fields: <String>[],
      bodyFields: <String>[
        for (final MapEntry<String, Object?> entry in map.entries)
          if (entry.key.isNotEmpty) posix.basenameWithoutExtension(entry.key)
      ]
          .map((final _) => convert ? _.toCamelCase() : _.normalize())
          .map((final String key) => '$key.hashCode'),
      separator: ' ^ ',
    )
    ..writeln('}');

  /// `Nested Groups`
  for (final MapEntry<String, Object?> entry in map.entries) {
    if (entry.key.isNotEmpty && entry.value is Map<String, Object?>) {
      generateModel(
        buffer,
        iconsMap,
        entry.key,
        keys: <String>[...keys, name],
      );
    }
  }
}