intersection method
Compute the intersection between this collection and another.
The result is a Set of all paths that, in theory, could contain
overlapping files or directories, taking into consideration all
settings of this and the other
collection.
Notice that this operation does not require looking at the file system.
Implementation
Set<String> intersection(FileCollection other) {
final otherDirsInDirs = directories
.expand((d) => other.directories.where((od) =>
d.isWithin(od.path, isDir: true) &&
(od.fileExtensions.isEmpty ||
od.fileExtensions.intersection(d.fileExtensions).isNotEmpty)))
.map((e) => e.path);
final dirsInOtherDirs = other.directories
.expand((od) => directories.where((d) =>
od.isWithin(d.path, isDir: true) &&
(d.fileExtensions.isEmpty ||
d.fileExtensions.intersection(od.fileExtensions).isNotEmpty)))
.map((e) => e.path);
final filesInOtherDirs = other.directories
.expand((d) => files.where((f) => d.isWithin(f, isDir: false)));
final otherFilesInDirs = directories
.expand((d) => other.files.where((f) => d.isWithin(f, isDir: false)));
final filesIntersection = files
.where((f) => other.includesFile(f))
.toSet()
.intersection(other.files.where((f) => includesFile(f)).toSet());
// all files must be acceptable by all collection's filters now
final filters = directories
.followedBy(other.directories)
.where((d) => d.fileExtensions.isNotEmpty)
.map((d) => d.fileExtensions);
bool Function(String) filter;
if (filters.isNotEmpty) {
final extensions = filters.fold(
filters.first, (Set<String> a, Set<String> b) => a.intersection(b));
filter = (s) => extensions.any(s.endsWith);
} else {
filter = (s) => true;
}
return filesIntersection
.followedBy(filesInOtherDirs)
.followedBy(otherFilesInDirs)
.where(filter)
.followedBy(otherDirsInDirs)
.followedBy(dirsInOtherDirs)
.toSet();
}