From fb2a6088dcc7b57a2c1ac93ec6a8fbcc52584734 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 13 May 2020 13:49:43 +0200 Subject: first attempt at sorting output This does currently not work yet, as we cannot call .finish() on dyn Aggregator. This needs to be adjusted. However, this provides the basic infrastructure for producing sorted output, including the required command line parsing. --- src/output/aggregators.rs | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) (limited to 'src/output/aggregators.rs') diff --git a/src/output/aggregators.rs b/src/output/aggregators.rs index 1b04af3..4fa2558 100644 --- a/src/output/aggregators.rs +++ b/src/output/aggregators.rs @@ -6,12 +6,15 @@ //! //! Aggregators must be shareable across threads, as the search will be multi-threaded. This is why //! an Aggregator must make sure that the data is protected by a mutex or similar. -use super::{super::LogResult, formats::Format}; +use super::{super::LogResult, formats::Format, sorting::Sorting}; -use std::io::Write; +use std::{ + io::Write, + sync::Mutex, +}; pub trait Aggregator: Sync { - fn push_item(&self, item: &LogResult, format: &dyn Format, stream: &mut dyn Write); + fn push_item(&self, item: LogResult, format: &dyn Format, stream: &mut dyn Write); fn finish(self, format: &dyn Format, stream: &mut dyn Write); } @@ -20,11 +23,44 @@ pub trait Aggregator: Sync { pub struct WriteThrough; impl Aggregator for WriteThrough { - fn push_item(&self, item: &LogResult, format: &dyn Format, stream: &mut dyn Write) { - let text = format.format_result(item); + fn push_item(&self, item: LogResult, format: &dyn Format, stream: &mut dyn Write) { + let text = format.format_result(&item); stream.write_all(text.as_bytes()).unwrap(); stream.flush().unwrap(); } fn finish(self, _: &dyn Format, _: &mut dyn Write) {} } + +/// An aggregator that keeps all found logs in memory and sorts them before outputting them. +#[derive(Debug)] +pub struct SortedOutput { + sorting: Sorting, + items: Mutex>, +} + +impl SortedOutput { + pub fn new(sorting: Sorting) -> Self { + SortedOutput { + sorting, + items: Mutex::new(vec![]), + } + } +} + +impl Aggregator for SortedOutput { + fn push_item(&self, item: LogResult, _: &dyn Format, _: &mut dyn Write) { + self.items.lock().unwrap().push(item) + } + + fn finish(self, format: &dyn Format, stream: &mut dyn Write) { + let SortedOutput { sorting, items } = self; + let mut items = items.into_inner().unwrap(); + items.sort_unstable_by(|a, b| sorting.cmp(a, b)); + for item in items { + let text = format.format_result(&item); + stream.write_all(text.as_bytes()).unwrap(); + } + stream.flush().unwrap(); + } +} -- cgit v1.2.3 From b6a13c465983993ac581051bb24a13d4296731a1 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 13 May 2020 16:33:27 +0200 Subject: fix Aggregator::finish for trait objects --- src/output/aggregators.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/output/aggregators.rs') diff --git a/src/output/aggregators.rs b/src/output/aggregators.rs index 4fa2558..24adbf8 100644 --- a/src/output/aggregators.rs +++ b/src/output/aggregators.rs @@ -15,7 +15,8 @@ use std::{ pub trait Aggregator: Sync { fn push_item(&self, item: LogResult, format: &dyn Format, stream: &mut dyn Write); - fn finish(self, format: &dyn Format, stream: &mut dyn Write); + // When the `unsized_locals` feature is stable, we could rewrite this to finish(self, ...). + fn finish(self: Box, format: &dyn Format, stream: &mut dyn Write); } /// An aggregator that just pushes through each item to the output stream without any sorting or @@ -29,7 +30,7 @@ impl Aggregator for WriteThrough { stream.flush().unwrap(); } - fn finish(self, _: &dyn Format, _: &mut dyn Write) {} + fn finish(self: Box, _: &dyn Format, _: &mut dyn Write) {} } /// An aggregator that keeps all found logs in memory and sorts them before outputting them. @@ -53,8 +54,8 @@ impl Aggregator for SortedOutput { self.items.lock().unwrap().push(item) } - fn finish(self, format: &dyn Format, stream: &mut dyn Write) { - let SortedOutput { sorting, items } = self; + fn finish(self: Box, format: &dyn Format, stream: &mut dyn Write) { + let SortedOutput { sorting, items } = *self; let mut items = items.into_inner().unwrap(); items.sort_unstable_by(|a, b| sorting.cmp(a, b)); for item in items { -- cgit v1.2.3 From 57b74f50e59a3fab2d74bbb6165d48ce3e6e2049 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 13 May 2020 17:03:58 +0200 Subject: fix formatting --- src/output/aggregators.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/output/aggregators.rs') diff --git a/src/output/aggregators.rs b/src/output/aggregators.rs index 24adbf8..83171eb 100644 --- a/src/output/aggregators.rs +++ b/src/output/aggregators.rs @@ -8,10 +8,7 @@ //! an Aggregator must make sure that the data is protected by a mutex or similar. use super::{super::LogResult, formats::Format, sorting::Sorting}; -use std::{ - io::Write, - sync::Mutex, -}; +use std::{io::Write, sync::Mutex}; pub trait Aggregator: Sync { fn push_item(&self, item: LogResult, format: &dyn Format, stream: &mut dyn Write); -- cgit v1.2.3