merge static method

MetaInfo merge(
  1. MetaInfo primary,
  2. List<MetaInfo> fallbacks, {
  3. required MetaMergePreference preference,
})

Merge primary metadata with fallbacks with difference preference applied.

Please see MetaMergePreference for merging options.

Implementation

static MetaInfo merge(MetaInfo primary, List<MetaInfo> fallbacks,
    {required MetaMergePreference preference}) {
  final Iterable<MetaInfo> validFallbacks =
      fallbacks.where((element) => !identical(element, primary)).toSet();

  if (validFallbacks.isEmpty) {
    throw ArgumentError(
        "Empty fallbacks or fill with primary MetaInfo itself into fallbacks are forbidden.");
  }

  T? findFirstNonBlankFallback<T extends Object>(
      T? Function(MetaInfo m) filter) {
    Iterable<T> selectedFields = validFallbacks
        .map(filter)
        .where((element) => element != null)
        .cast<T>();

    return selectedFields.isEmpty ? null : selectedFields.first;
  }

  switch (preference) {
    case MetaMergePreference.fillTheBlank:
      return MetaInfo._(
          primary.title ?? findFirstNonBlankFallback<String>((m) => m.title),
          primary.url ?? findFirstNonBlankFallback<Uri>((m) => m.url),
          primary.secureUrl ??
              findFirstNonBlankFallback<Uri>((m) => m.secureUrl),
          primary.description ??
              findFirstNonBlankFallback<String>((m) => m.description),
          primary.siteName ??
              findFirstNonBlankFallback<String>((m) => m.siteName),
          primary.audios,
          primary.images,
          primary.videos);
    case MetaMergePreference.appendMediaOnly:
      return MetaInfo._(
          primary.title,
          primary.url,
          primary.secureUrl,
          primary.description,
          primary.siteName,
          List.unmodifiable(<AudioInfo>[
            ...primary.audios,
            ...fallbacks.map((e) => e.audios).expand((element) => element)
          ]),
          List.unmodifiable(<ImageInfo>[
            ...primary.images,
            ...fallbacks.map((e) => e.images).expand((element) => element)
          ]),
          List.unmodifiable(<VideoInfo>[
            ...primary.videos,
            ...fallbacks.map((e) => e.videos).expand((element) => element)
          ]));
  }
}