,
-}
-
-impl std::ops::BitAnd for EntryPredicateBuilder {
- type Output = EntryPredicateBuilder;
-
- fn bitand(self, rhs: Self) -> Self::Output {
- match (self.candidate, rhs.candidate) {
- (None, None) =>
- EntryPredicateBuilder::new(),
- (Some(mut lhs), Some(mut rhs)) => {
- EntryPredicateBuilder::from(move |entry| {
- let result = lhs(entry);
- if result {
- rhs(entry)
- } else {
- result
- }
- })
- }
- (None, some) =>
- EntryPredicateBuilder { candidate: some },
- (some, None) =>
- EntryPredicateBuilder { candidate: some },
- }
- }
-}
-
-impl std::ops::Not for EntryPredicateBuilder {
- type Output = EntryPredicateBuilder;
-
- fn not(self) -> Self::Output {
- match self.candidate {
- Some(mut original) => {
- Self::from(move |entry| {
- let result = original(entry);
- !result
- })
- }
- None =>
- Self::new(),
- }
- }
-}
-
-impl EntryPredicateBuilder {
- /// Creates an entry predicate from the builder.
- pub fn build(self) -> EntryPredicate {
- match self.candidate {
- Some(predicate) => predicate,
- None => Box::new(|_: &Entry| true),
- }
- }
-
- /// Construct a predicate builder that is empty.
- #[inline]
- fn new() -> Self {
- Self { candidate: None }
- }
-
- /// Construct a predicate builder that implements a predicate.
- #[inline]
- fn from(predicate: P) -> Self
- where
- P: FnMut(&Entry) -> bool + 'static,
- {
- Self { candidate: Some(Box::new(predicate)) }
- }
-
- /// Create a predicate that filters out entries
- /// that are using one of the given compilers.
- pub fn filter_by_compiler_paths(paths: Vec) -> Self {
- if paths.is_empty() {
- Self::new()
- } else {
- Self::from(move |entry| {
- let compiler = PathBuf::from(entry.arguments[0].as_str());
- // return true if none of the paths are a prefix of the compiler path.
- paths.iter().any(|path| { !compiler.starts_with(path) })
- })
- }
- }
-
- /// Create a predicate that filters out entries
- /// that are using one of the given compiler arguments.
- pub fn filter_by_compiler_arguments(flags: Vec) -> Self {
- if flags.is_empty() {
- Self::new()
- } else {
- Self::from(move |entry| {
- let mut arguments = entry.arguments.iter().skip(1);
- // return true if none of the flags are in the arguments.
- arguments.all(|argument| { !flags.contains(&argument) })
- })
- }
- }
-
- /// Create a predicate that filters out entries
- /// that are not using any of the given source paths.
- pub fn filter_by_source_paths(paths: Vec) -> Self {
- if paths.is_empty() {
- Self::new()
- } else {
- Self::from(move |entry| {
- paths.iter().any(|path| { entry.file.starts_with(path) })
- })
- }
- }
-
- /// Create a predicate that filters out entries
- /// that source file does not exist.
- pub fn filter_by_source_existence(only_existing: bool) -> Self {
- if only_existing {
- Self::from(|entry| { entry.file.is_file() })
- } else {
- Self::new()
- }
- }
-
- /// Create a predicate that filters out entries
- /// that are already in the compilation database based on their hash.
- pub fn filter_duplicate_entries(hash_function: impl Fn(&Entry) -> u64 + 'static) -> Self {
- let mut have_seen = HashSet::new();
-
- Self::from(move |entry| {
- let hash = hash_function(entry);
- if !have_seen.contains(&hash) {
- have_seen.insert(hash);
- true
- } else {
- false
- }
- })
- }
-}
-
-impl TryFrom<&config::Filter> for EntryPredicate {
- type Error = anyhow::Error;
-
- /// Create a filter from the configuration.
- fn try_from(config: &config::Filter) -> Result {
- // - Check if the source file exists
- // - Check if the source file is not in the exclude list of the configuration
- // - Check if the source file is in the include list of the configuration
- let source_exist_check = EntryPredicateBuilder::filter_by_source_existence(
- config.source.include_only_existing_files,
- );
- let source_paths_to_exclude = EntryPredicateBuilder::filter_by_source_paths(
- config.source.paths_to_exclude.clone(),
- );
- let source_paths_to_include = EntryPredicateBuilder::filter_by_source_paths(
- config.source.paths_to_include.clone(),
- );
- let source_checks = source_exist_check & !source_paths_to_exclude & source_paths_to_include;
- // - Check if the compiler path is not in the list of the configuration
- // - Check if the compiler arguments are not in the list of the configuration
- let compiler_with_path = EntryPredicateBuilder::filter_by_compiler_paths(
- config.compilers.with_paths.clone(),
- );
- let compiler_with_argument = EntryPredicateBuilder::filter_by_compiler_arguments(
- config.compilers.with_arguments.clone(),
- );
- let compiler_checks = !compiler_with_path & !compiler_with_argument;
- // - Check if the entry is not a duplicate based on the fields of the configuration
- let hash_function = create_hash(config.duplicates.by_fields.clone());
- let duplicates = EntryPredicateBuilder::filter_duplicate_entries(hash_function);
-
- Ok((source_checks & compiler_checks & duplicates).build())
- }
-}
-
-fn create_hash(fields: Vec) -> impl Fn(&Entry) -> u64 + 'static {
- move |entry: &Entry| {
- let mut hasher = DefaultHasher::new();
- for field in &fields {
- match field {
- config::OutputFields::Directory => entry.directory.hash(&mut hasher),
- config::OutputFields::File => entry.file.hash(&mut hasher),
- config::OutputFields::Arguments => entry.arguments.hash(&mut hasher),
- config::OutputFields::Output => entry.output.hash(&mut hasher),
- }
- }
- hasher.finish()
- }
-}
-
-#[cfg(test)]
-mod test {
- use std::hash::{Hash, Hasher};
- use crate::{vec_of_pathbuf, vec_of_strings};
- use super::*;
-
- #[test]
- fn test_filter_by_compiler_paths() {
- let input: Vec = vec![
- Entry {
- file: PathBuf::from("/home/user/project/source.c"),
- arguments: vec_of_strings!["cc", "-c", "source.c"],
- directory: PathBuf::from("/home/user/project"),
- output: None,
- },
- Entry {
- file: PathBuf::from("/home/user/project/source.c++"),
- arguments: vec_of_strings!["c++", "-c", "source.c++"],
- directory: PathBuf::from("/home/user/project"),
- output: None,
- },
- Entry {
- file: PathBuf::from("/home/user/project/test.c"),
- arguments: vec_of_strings!["cc", "-c", "test.c"],
- directory: PathBuf::from("/home/user/project"),
- output: None,
- },
- ];
-
- let expected: Vec = vec![
- input[0].clone(),
- input[2].clone(),
- ];
-
- let sut: EntryPredicate = EntryPredicateBuilder::filter_by_compiler_paths(vec_of_pathbuf!["c++"]).build();
- let result: Vec = input.into_iter().filter(sut).collect();
- assert_eq!(result, expected);
- }
-
- #[test]
- fn test_filter_by_compiler_arguments() {
- let input: Vec = vec![
- Entry {
- file: PathBuf::from("/home/user/project/source.c"),
- arguments: vec_of_strings!["cc", "-c", "source.c"],
- directory: PathBuf::from("/home/user/project"),
- output: None,
- },
- Entry {
- file: PathBuf::from("/home/user/project/source.c"),
- arguments: vec_of_strings!["cc", "-cc1", "source.c"],
- directory: PathBuf::from("/home/user/project"),
- output: None,
- },
- Entry {
- file: PathBuf::from("/home/user/project/test.c"),
- arguments: vec_of_strings!["cc", "-c", "test.c"],
- directory: PathBuf::from("/home/user/project"),
- output: None,
- },
- ];
-
- let expected: Vec = vec![
- input[0].clone(),
- input[2].clone(),
- ];
-
- let sut: EntryPredicate = EntryPredicateBuilder::filter_by_compiler_arguments(vec_of_strings!["-cc1"]).build();
- let result: Vec = input.into_iter().filter(sut).collect();
- assert_eq!(result, expected);
- }
-
- #[test]
- fn test_filter_by_source_paths() {
- let paths_to_include = vec_of_pathbuf!["/home/user/project/source"];
- let paths_to_exclude = vec_of_pathbuf!["/home/user/project/test"];
-
- let input: Vec = vec![
- Entry {
- file: PathBuf::from("/home/user/project/source/source.c"),
- arguments: vec_of_strings!["cc", "-c", "source.c"],
- directory: PathBuf::from("/home/user/project"),
- output: None,
- },
- Entry {
- file: PathBuf::from("/home/user/project/test/source.c"),
- arguments: vec_of_strings!["cc", "-c", "test.c"],
- directory: PathBuf::from("/home/user/project"),
- output: None,
- },
- ];
-
- let expected: Vec = vec![
- input[0].clone(),
- ];
-
- let sut: EntryPredicate = (
- EntryPredicateBuilder::filter_by_source_paths(paths_to_include) &
- !EntryPredicateBuilder::filter_by_source_paths(paths_to_exclude)
- ).build();
- let result: Vec = input.into_iter().filter(sut).collect();
- assert_eq!(result, expected);
- }
-
- #[test]
- fn test_duplicate_detection_works() {
- let input: Vec = vec![
- Entry {
- file: PathBuf::from("/home/user/project/source.c"),
- arguments: vec_of_strings!["cc", "-c", "source.c"],
- directory: PathBuf::from("/home/user/project"),
- output: Some(PathBuf::from("/home/user/project/source.o")),
- },
- Entry {
- file: PathBuf::from("/home/user/project/source.c"),
- arguments: vec_of_strings!["cc", "-c", "-Wall", "source.c"],
- directory: PathBuf::from("/home/user/project"),
- output: Some(PathBuf::from("/home/user/project/source.o")),
- },
- Entry {
- file: PathBuf::from("/home/user/project/source.c"),
- arguments: vec_of_strings!["cc", "-c", "source.c", "-o", "test.o"],
- directory: PathBuf::from("/home/user/project"),
- output: Some(PathBuf::from("/home/user/project/test.o")),
- },
- ];
-
- let expected: Vec = vec![
- input[0].clone(),
- input[2].clone(),
- ];
-
- let hash_function = |entry: &Entry| {
- let mut hasher = std::collections::hash_map::DefaultHasher::new();
- entry.file.hash(&mut hasher);
- entry.output.hash(&mut hasher);
- hasher.finish()
- };
- let sut: EntryPredicate = EntryPredicateBuilder::filter_duplicate_entries(hash_function).build();
- let result: Vec = input.into_iter().filter(sut).collect();
- assert_eq!(result, expected);
- }
-}
\ No newline at end of file
diff --git a/rust/bear/src/main.rs b/rust/bear/src/main.rs
index 24e9a809..083b795f 100644
--- a/rust/bear/src/main.rs
+++ b/rust/bear/src/main.rs
@@ -27,7 +27,6 @@ use semantic;
mod args;
mod config;
mod input;
-mod filter;
mod fixtures;
mod output;
diff --git a/rust/bear/src/output/filter.rs b/rust/bear/src/output/filter.rs
new file mode 100644
index 00000000..1749b8aa
--- /dev/null
+++ b/rust/bear/src/output/filter.rs
@@ -0,0 +1,361 @@
+/* Copyright (C) 2012-2024 by László Nagy
+ This file is part of Bear.
+
+ Bear is a tool to generate compilation database for clang tooling.
+
+ Bear is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Bear is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+use std::hash::Hash;
+use std::path::PathBuf;
+
+use super::config;
+use builder::create_hash;
+use builder::EntryPredicateBuilder as Builder;
+use json_compilation_db::Entry;
+
+/// A predicate that can be used to filter compilation database entries.
+///
+/// If the predicate returns `true`, the entry is included in the result set.
+/// If the predicate returns `false`, the entry is excluded from the result set.
+pub type EntryPredicate = Box bool>;
+
+impl TryFrom<&config::Filter> for EntryPredicate {
+ type Error = anyhow::Error;
+
+ /// Create a filter from the configuration.
+ fn try_from(config: &config::Filter) -> Result {
+ // - Check if the source file exists
+ // - Check if the source file is not in the exclude list of the configuration
+ // - Check if the source file is in the include list of the configuration
+ let source_exist_check =
+ Builder::filter_by_source_existence(config.source.include_only_existing_files);
+ let source_paths_to_exclude =
+ Builder::filter_by_source_paths(&config.source.paths_to_exclude);
+ let source_paths_to_include =
+ Builder::filter_by_source_paths(&config.source.paths_to_include);
+ let source_checks = source_exist_check & !source_paths_to_exclude & source_paths_to_include;
+ // - Check if the compiler path is not in the list of the configuration
+ // - Check if the compiler arguments are not in the list of the configuration
+ let compiler_with_path = Builder::filter_by_compiler_paths(&config.compilers.with_paths);
+ let compiler_with_argument =
+ Builder::filter_by_compiler_arguments(&config.compilers.with_arguments);
+ let compiler_checks = !compiler_with_path & !compiler_with_argument;
+ // - Check if the entry is not a duplicate based on the fields of the configuration
+ let hash_function = create_hash(&config.duplicates.by_fields);
+ let duplicates = Builder::filter_duplicate_entries(hash_function);
+
+ Ok((source_checks & compiler_checks & duplicates).build())
+ }
+}
+
+mod builder {
+ use super::*;
+ use std::collections::HashSet;
+ use std::hash::{DefaultHasher, Hasher};
+
+ /// Represents a builder object that can be used to construct an entry predicate.
+ pub(super) struct EntryPredicateBuilder {
+ candidate: Option,
+ }
+
+ impl EntryPredicateBuilder {
+ /// Creates an entry predicate from the builder.
+ pub(super) fn build(self) -> EntryPredicate {
+ match self.candidate {
+ Some(predicate) => predicate,
+ None => Box::new(|_: &Entry| true),
+ }
+ }
+
+ /// Construct a predicate builder that is empty.
+ #[inline]
+ fn new() -> Self {
+ Self { candidate: None }
+ }
+
+ /// Construct a predicate builder that implements a predicate.
+ #[inline]
+ fn from(predicate: P) -> Self
+ where
+ P: FnMut(&Entry) -> bool + 'static,
+ {
+ Self {
+ candidate: Some(Box::new(predicate)),
+ }
+ }
+
+ /// Create a predicate that filters out entries
+ /// that are using one of the given compilers.
+ pub(super) fn filter_by_compiler_paths(paths: &[PathBuf]) -> Self {
+ if paths.is_empty() {
+ Self::new()
+ } else {
+ let owned_paths: Vec = paths.iter().cloned().collect();
+ Self::from(move |entry| {
+ let compiler = PathBuf::from(entry.arguments[0].as_str());
+ // return true if none of the paths are a prefix of the compiler path.
+ owned_paths.iter().any(|path| !compiler.starts_with(path))
+ })
+ }
+ }
+
+ /// Create a predicate that filters out entries
+ /// that are using one of the given compiler arguments.
+ pub(super) fn filter_by_compiler_arguments(flags: &[String]) -> Self {
+ if flags.is_empty() {
+ Self::new()
+ } else {
+ let owned_flags: HashSet = flags.iter().cloned().collect();
+ Self::from(move |entry| {
+ let mut arguments = entry.arguments.iter().skip(1);
+ // return true if none of the flags are in the arguments.
+ arguments.all(|argument| !owned_flags.contains(argument))
+ })
+ }
+ }
+
+ /// Create a predicate that filters out entries
+ /// that are not using any of the given source paths.
+ pub(super) fn filter_by_source_paths(paths: &[PathBuf]) -> Self {
+ if paths.is_empty() {
+ Self::new()
+ } else {
+ let owned_paths: Vec = paths.iter().cloned().collect();
+ Self::from(move |entry| owned_paths.iter().any(|path| entry.file.starts_with(path)))
+ }
+ }
+
+ /// Create a predicate that filters out entries
+ /// that source file does not exist.
+ pub(super) fn filter_by_source_existence(only_existing: bool) -> Self {
+ if only_existing {
+ Self::from(|entry| entry.file.is_file())
+ } else {
+ Self::new()
+ }
+ }
+
+ /// Create a predicate that filters out entries
+ /// that are already in the compilation database based on their hash.
+ pub(super) fn filter_duplicate_entries(
+ hash_function: impl Fn(&Entry) -> u64 + 'static,
+ ) -> Self {
+ let mut have_seen = HashSet::new();
+
+ Self::from(move |entry| {
+ let hash = hash_function(entry);
+ if !have_seen.contains(&hash) {
+ have_seen.insert(hash);
+ true
+ } else {
+ false
+ }
+ })
+ }
+ }
+
+ // FIXME: write unit tests for the combination operators.
+ /// Implement the AND operator for combining predicates.
+ impl std::ops::BitAnd for EntryPredicateBuilder {
+ type Output = EntryPredicateBuilder;
+
+ fn bitand(self, rhs: Self) -> Self::Output {
+ match (self.candidate, rhs.candidate) {
+ (None, None) => EntryPredicateBuilder::new(),
+ (None, some) => EntryPredicateBuilder { candidate: some },
+ (some, None) => EntryPredicateBuilder { candidate: some },
+ (Some(mut lhs), Some(mut rhs)) => EntryPredicateBuilder::from(move |entry| {
+ let result = lhs(entry);
+ if result {
+ rhs(entry)
+ } else {
+ result
+ }
+ }),
+ }
+ }
+ }
+
+ // FIXME: write unit tests for the combination operators.
+ /// Implement the NOT operator for combining predicates.
+ impl std::ops::Not for EntryPredicateBuilder {
+ type Output = EntryPredicateBuilder;
+
+ fn not(self) -> Self::Output {
+ match self.candidate {
+ Some(mut original) => Self::from(move |entry| {
+ let result = original(entry);
+ !result
+ }),
+ None => Self::new(),
+ }
+ }
+ }
+
+ // FIXME: write unit tests for the hash function.
+ /// Create a hash function that is using the given fields to calculate the hash of an entry.
+ pub(super) fn create_hash(fields: &[config::OutputFields]) -> impl Fn(&Entry) -> u64 + 'static {
+ let owned_fields: Vec = fields.iter().cloned().collect();
+ move |entry: &Entry| {
+ let mut hasher = DefaultHasher::new();
+ for field in &owned_fields {
+ match field {
+ config::OutputFields::Directory => entry.directory.hash(&mut hasher),
+ config::OutputFields::File => entry.file.hash(&mut hasher),
+ config::OutputFields::Arguments => entry.arguments.hash(&mut hasher),
+ config::OutputFields::Output => entry.output.hash(&mut hasher),
+ }
+ }
+ hasher.finish()
+ }
+ }
+
+ #[cfg(test)]
+ mod test {
+ use super::*;
+ use crate::{vec_of_pathbuf, vec_of_strings};
+ use std::hash::{Hash, Hasher};
+
+ #[test]
+ fn test_filter_by_compiler_paths() {
+ let input: Vec = vec![
+ Entry {
+ file: PathBuf::from("/home/user/project/source.c"),
+ arguments: vec_of_strings!["cc", "-c", "source.c"],
+ directory: PathBuf::from("/home/user/project"),
+ output: None,
+ },
+ Entry {
+ file: PathBuf::from("/home/user/project/source.c++"),
+ arguments: vec_of_strings!["c++", "-c", "source.c++"],
+ directory: PathBuf::from("/home/user/project"),
+ output: None,
+ },
+ Entry {
+ file: PathBuf::from("/home/user/project/test.c"),
+ arguments: vec_of_strings!["cc", "-c", "test.c"],
+ directory: PathBuf::from("/home/user/project"),
+ output: None,
+ },
+ ];
+
+ let expected: Vec = vec![input[0].clone(), input[2].clone()];
+
+ let sut: EntryPredicate =
+ EntryPredicateBuilder::filter_by_compiler_paths(&vec_of_pathbuf!["c++"]).build();
+ let result: Vec = input.into_iter().filter(sut).collect();
+ assert_eq!(result, expected);
+ }
+
+ #[test]
+ fn test_filter_by_compiler_arguments() {
+ let input: Vec = vec![
+ Entry {
+ file: PathBuf::from("/home/user/project/source.c"),
+ arguments: vec_of_strings!["cc", "-c", "source.c"],
+ directory: PathBuf::from("/home/user/project"),
+ output: None,
+ },
+ Entry {
+ file: PathBuf::from("/home/user/project/source.c"),
+ arguments: vec_of_strings!["cc", "-cc1", "source.c"],
+ directory: PathBuf::from("/home/user/project"),
+ output: None,
+ },
+ Entry {
+ file: PathBuf::from("/home/user/project/test.c"),
+ arguments: vec_of_strings!["cc", "-c", "test.c"],
+ directory: PathBuf::from("/home/user/project"),
+ output: None,
+ },
+ ];
+
+ let expected: Vec = vec![input[0].clone(), input[2].clone()];
+
+ let sut: EntryPredicate =
+ EntryPredicateBuilder::filter_by_compiler_arguments(&vec_of_strings!["-cc1"])
+ .build();
+ let result: Vec = input.into_iter().filter(sut).collect();
+ assert_eq!(result, expected);
+ }
+
+ #[test]
+ fn test_filter_by_source_paths() {
+ let paths_to_include = vec_of_pathbuf!["/home/user/project/source"];
+ let paths_to_exclude = vec_of_pathbuf!["/home/user/project/test"];
+
+ let input: Vec = vec![
+ Entry {
+ file: PathBuf::from("/home/user/project/source/source.c"),
+ arguments: vec_of_strings!["cc", "-c", "source.c"],
+ directory: PathBuf::from("/home/user/project"),
+ output: None,
+ },
+ Entry {
+ file: PathBuf::from("/home/user/project/test/source.c"),
+ arguments: vec_of_strings!["cc", "-c", "test.c"],
+ directory: PathBuf::from("/home/user/project"),
+ output: None,
+ },
+ ];
+
+ let expected: Vec = vec![input[0].clone()];
+
+ let sut: EntryPredicate =
+ (EntryPredicateBuilder::filter_by_source_paths(&paths_to_include)
+ & !EntryPredicateBuilder::filter_by_source_paths(&paths_to_exclude))
+ .build();
+ let result: Vec = input.into_iter().filter(sut).collect();
+ assert_eq!(result, expected);
+ }
+
+ #[test]
+ fn test_duplicate_detection_works() {
+ let input: Vec = vec![
+ Entry {
+ file: PathBuf::from("/home/user/project/source.c"),
+ arguments: vec_of_strings!["cc", "-c", "source.c"],
+ directory: PathBuf::from("/home/user/project"),
+ output: Some(PathBuf::from("/home/user/project/source.o")),
+ },
+ Entry {
+ file: PathBuf::from("/home/user/project/source.c"),
+ arguments: vec_of_strings!["cc", "-c", "-Wall", "source.c"],
+ directory: PathBuf::from("/home/user/project"),
+ output: Some(PathBuf::from("/home/user/project/source.o")),
+ },
+ Entry {
+ file: PathBuf::from("/home/user/project/source.c"),
+ arguments: vec_of_strings!["cc", "-c", "source.c", "-o", "test.o"],
+ directory: PathBuf::from("/home/user/project"),
+ output: Some(PathBuf::from("/home/user/project/test.o")),
+ },
+ ];
+
+ let expected: Vec = vec![input[0].clone(), input[2].clone()];
+
+ let hash_function = |entry: &Entry| {
+ let mut hasher = DefaultHasher::new();
+ entry.file.hash(&mut hasher);
+ entry.output.hash(&mut hasher);
+ hasher.finish()
+ };
+ let sut: EntryPredicate =
+ EntryPredicateBuilder::filter_duplicate_entries(hash_function).build();
+ let result: Vec = input.into_iter().filter(sut).collect();
+ assert_eq!(result, expected);
+ }
+ }
+}
diff --git a/rust/bear/src/output.rs b/rust/bear/src/output/mod.rs
similarity index 97%
rename from rust/bear/src/output.rs
rename to rust/bear/src/output/mod.rs
index edbfb012..43b3b6fd 100644
--- a/rust/bear/src/output.rs
+++ b/rust/bear/src/output/mod.rs
@@ -21,13 +21,15 @@ use std::fs::{File, OpenOptions};
use std::io::{BufReader, BufWriter};
use std::path::{Path, PathBuf};
-use crate::{args, config, filter};
+use super::{args, config};
use anyhow::{anyhow, Context, Result};
use json_compilation_db::Entry;
use path_absolutize::Absolutize;
use semantic;
use serde_json::Error;
+mod filter;
+
/// Responsible for writing the final compilation database file.
///
/// Implements filtering, formatting and atomic file writing.
@@ -81,10 +83,7 @@ impl OutputWriter {
}
}
- fn write_into_compilation_db(
- &self,
- entries: impl Iterator- ,
- ) -> Result<()> {
+ fn write_into_compilation_db(&self, entries: impl Iterator
- ) -> Result<()> {
// Filter out the entries as per the configuration.
let filter: filter::EntryPredicate = TryFrom::try_from(&self.filter)?;
let filtered_entries = entries.filter(filter);
@@ -152,9 +151,7 @@ fn validate_filter(filter: &config::Filter) -> config::Filter {
source: filter.source.clone(),
compilers: filter.compilers.clone(),
duplicates: config::DuplicateFilter {
- by_fields: validate_duplicates_by_fields(
- filter.duplicates.by_fields.as_slice(),
- ),
+ by_fields: validate_duplicates_by_fields(filter.duplicates.by_fields.as_slice()),
},
}
}