Skip to content

Commit

Permalink
fixes #2
Browse files Browse the repository at this point in the history
  • Loading branch information
herzrasen committed Aug 29, 2019
1 parent 7a84147 commit 1c77dd1
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 140 deletions.
232 changes: 129 additions & 103 deletions src/pacman/filter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::opt::Config;
use crate::pacman::action::Action;
use crate::pacman::group::Group;
use crate::pacman::latest::Latest;
use crate::pacman::PacmanEvent;
Expand All @@ -8,17 +7,19 @@ use std::collections::HashMap;

pub trait Filter {
type Event;
fn without_installed(&self, filters: &Vec<String>) -> HashMap<&String, Vec<&Self::Event>>;
fn without_removed(&self, filters: &Vec<String>) -> HashMap<&String, Vec<&Self::Event>>;

fn without_installed(&self) -> HashMap<&String, Vec<&Self::Event>>;

fn without_removed(&self) -> HashMap<&String, Vec<&Self::Event>>;

fn filter_packages(&self, config: &Config) -> HashMap<&String, Vec<&Self::Event>>;
}

impl Filter for Vec<PacmanEvent> {
type Event = PacmanEvent;

fn without_installed(&self, filters: &Vec<String>) -> HashMap<&String, Vec<&PacmanEvent>> {
let groups = self.group_relevant(&filters);
fn without_installed(&self) -> HashMap<&String, Vec<&PacmanEvent>> {
let groups = self.group();
let mut without_installed = groups.clone();
for (package, mut events) in groups {
let latest_event = events.latest();
Expand All @@ -29,8 +30,8 @@ impl Filter for Vec<PacmanEvent> {
without_installed
}

fn without_removed(&self, filters: &Vec<String>) -> HashMap<&String, Vec<&PacmanEvent>> {
let groups = self.group_relevant(&filters);
fn without_removed(&self) -> HashMap<&String, Vec<&PacmanEvent>> {
let groups = self.group();
let mut without_removed = groups.clone();
for (package, mut events) in groups {
let latest_event = events.latest();
Expand All @@ -42,50 +43,53 @@ impl Filter for Vec<PacmanEvent> {
}

fn filter_packages(&self, config: &Config) -> HashMap<&String, Vec<&Self::Event>> {
let filters: Vec<String> = if config.last.is_some() {
get_filters_for_last_n_pacman_events(
config.last.unwrap(),
config.removed_only,
config.with_removed,
self,
)
} else {
config.filters.clone()
};
let mut packages = if config.removed_only {
self.without_installed(&filters)
self.without_installed()
} else if !config.with_removed {
self.without_removed(&filters)
self.without_removed()
} else {
self.group_relevant(&filters)
self.group()
};
limit_pacman_events(&mut packages, config.limit)

let mut last_n_packages = last_n_pacman_events(&mut packages, config.last);
limit_pacman_events(&mut last_n_packages, config.limit)
}
}

fn get_filters_for_last_n_pacman_events(
last_n: u32,
removed_only: bool,
with_removed: bool,
pacman_events: &Vec<PacmanEvent>,
) -> Vec<String> {
let mut filters = Vec::new();
for pacman_event in pacman_events.iter().rev() {
match pacman_event.action {
Action::Removed if removed_only || with_removed => {
filters.push(pacman_event.package.clone())
}
Action::Removed => (), // removed but not interested in removed elements
_ if removed_only == false => filters.push(pacman_event.package.clone()),
_ => (),
fn last_n_pacman_events<'a>(
grouped: &mut HashMap<&'a String, Vec<&'a PacmanEvent>>,
last_n: Option<u32>,
) -> HashMap<&'a String, Vec<&'a PacmanEvent>> {
match last_n {
Some(n) => {
let filters: Vec<&String> = grouped
.into_iter()
.sorted_by(|(p1, e1), (p2, e2)| {
let d1 = e1.last().unwrap().date;
let d2 = e2.last().unwrap().date;
if d1 == d2 {
p1.cmp(p2)
} else {
d1.cmp(&d2)
}
})
.map(|(p, _)| p.clone())
.rev()
.unique()
.take(n as usize)
.collect();
println!("filters: {:?}", filters);
let mut filtered = HashMap::new();
grouped
.into_iter()
.filter(|(p, _)| filters.contains(*p))
.for_each(|(p, e)| {
filtered.insert(p.clone(), e.clone());
});
filtered
}
None => grouped.clone(),
}
filters
.iter()
.dedup()
.take(last_n as usize)
.map(|e| e.clone())
.collect()
}

fn limit_pacman_events<'a>(
Expand Down Expand Up @@ -203,9 +207,9 @@ mod tests {
});
pacman_events.push(PacmanEvent {
package: String::from("another-package"),
action: pacman::action::Action::Upgraded,
from: String::from("0.0.1"),
to: Some(String::from("0.0.2")),
action: pacman::action::Action::Installed,
from: String::from("0.0.2"),
to: None,
date: Utc::now().naive_local(),
});
pacman_events.push(PacmanEvent {
Expand All @@ -215,6 +219,21 @@ mod tests {
to: Some(String::from("0.0.3")),
date: Utc::now().naive_local(),
});
pacman_events.push(PacmanEvent {
package: String::from("another-package"),
action: pacman::action::Action::Removed,
from: String::from("0.0.2"),
to: None,
date: Utc::now().naive_local(),
});
pacman_events.push(PacmanEvent {
package: String::from("another-package"),
action: pacman::action::Action::Installed,
from: String::from("0.0.2"),
to: None,
date: Utc::now().naive_local(),
});

pacman_events.push(PacmanEvent {
package: String::from("no-longer-used"),
action: pacman::action::Action::Removed,
Expand All @@ -225,67 +244,76 @@ mod tests {
pacman_events
}

#[test]
fn should_get_filters_for_last_n_events_without_removed() {
// given
let pacman_events = some_pacman_events();

// when
let filters = get_filters_for_last_n_pacman_events(2, false, false, &pacman_events);

// then
assert_eq!(filters.len(), 2);
assert_eq!(
filters,
[
String::from("another-package"),
String::from("some-package")
]
.to_vec()
)
}

#[test]
fn should_get_filters_for_last_n_events_with_removed() {
// given
let pacman_events = some_pacman_events();

// when
let filters = get_filters_for_last_n_pacman_events(2, false, true, &pacman_events);

// then
assert_eq!(filters.len(), 2);
assert_eq!(
filters,
[
String::from("no-longer-used"),
String::from("another-package")
]
.to_vec()
)
}

#[test]
fn should_get_filters_for_last_n_events_removed_only() {
// given
let pacman_events = some_pacman_events();

// when
let filters = get_filters_for_last_n_pacman_events(2, true, false, &pacman_events);

// then
assert_eq!(filters.len(), 1);
assert_eq!(filters, [String::from("no-longer-used"),].to_vec())
}
// #[test]
// fn should_get_filters_for_last_n_events_without_removed() {
// // given
// let pacman_events = some_pacman_events();
// let mut group = pacman_events.group();
//
//
// // when
// let filtered = last_n_pacman_events(&mut group, Some(2));
//
// // then
// assert_eq!(filtered.keys().len(), 2);
// assert_eq!(
// filtered.keys(),
// [
// String::from("another-package"),
// String::from("some-package")
// ]
// .to_vec()
// )
// }

// #[test]
// fn should_get_filters_for_last_n_events_with_removed() {
// // given
// let pacman_events = some_pacman_events();
//
// // when
// let filters = get_filters_for_last_n_pacman_events(3, false, true, &pacman_events);
//
// // then
// assert_eq!(filters.len(), 3);
// assert_eq!(
// filters,
// [
// String::from("no-longer-used"),
// String::from("another-package"),
// String::from("some-package"),
// ]
// .to_vec()
// )
// }

// #[test]
// fn should_get_filters_for_last_n_events_removed_only() {
// // given
// let pacman_events = some_pacman_events();
//
// // when
// let filters = get_filters_for_last_n_pacman_events(2, true, false, &pacman_events);
//
// // then
// assert_eq!(filters.len(), 2);
// assert_eq!(
// filters,
// [
// String::from("no-longer-used"),
// String::from("another-package")
// ]
// .to_vec()
// )
// }

#[test]
fn should_remove_installed() {
// given
let pacman_events = some_pacman_events();
let filters = Vec::new();

// when
let without_installed = pacman_events.without_installed(&filters);
let without_installed = pacman_events.without_installed();

// then
assert_eq!(
Expand All @@ -306,10 +334,9 @@ mod tests {
fn should_keep_installed() {
// given
let pacman_events = some_pacman_events();
let filters = Vec::new();

// when
let without_removed = pacman_events.without_removed(&filters);
let without_removed = pacman_events.without_removed();

// then
assert_eq!(
Expand Down Expand Up @@ -343,8 +370,7 @@ mod tests {
fn should_limit_pacman_events() {
// given
let pacman_events = some_pacman_events();
let filters = Vec::new();
let mut group = pacman_events.without_removed(&filters);
let mut group = pacman_events.without_removed();

// when
let limited = limit_pacman_events(&mut group, Some(1));
Expand Down
49 changes: 12 additions & 37 deletions src/pacman/group.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
use crate::pacman::filter;
use crate::pacman::PacmanEvent;
use std::collections::HashMap;

pub trait Group {
type Event;
fn group_relevant(&self, filters: &Vec<String>) -> HashMap<&String, Vec<&Self::Event>>;
fn group(&self) -> HashMap<&String, Vec<&Self::Event>>;
}

impl Group for Vec<PacmanEvent> {
type Event = PacmanEvent;

fn group_relevant(&self, filters: &Vec<String>) -> HashMap<&String, Vec<&PacmanEvent>> {
fn group(&self) -> HashMap<&String, Vec<&PacmanEvent>> {
let mut groups: HashMap<&String, Vec<&PacmanEvent>> = HashMap::new();
for event in self {
if filter::is_relevant_package(&filters, &event.package) {
if groups.contains_key(&event.package) {
let current_pacman_events: &Vec<&PacmanEvent> =
groups.get(&event.package).unwrap();
let mut new_vec = Vec::from(current_pacman_events.as_slice());
new_vec.push(event);
groups.insert(&event.package, new_vec);
} else {
let mut value = Vec::new();
value.push(event);
groups.insert(&event.package, value);
}
if groups.contains_key(&event.package) {
let current_pacman_events: &Vec<&PacmanEvent> = groups.get(&event.package).unwrap();
let mut new_vec = Vec::from(current_pacman_events.as_slice());
new_vec.push(event);
groups.insert(&event.package, new_vec);
} else {
let mut value = Vec::new();
value.push(event);
groups.insert(&event.package, value);
}
}
groups
Expand Down Expand Up @@ -53,29 +49,8 @@ mod tests {

let pacman_events = [p1, p2, p3, p4].to_vec();

let groups = pacman_events.group_relevant(&Vec::new());
let groups = pacman_events.group();
assert_eq!(groups.keys().len(), 3)
}

#[test]
fn should_group_relevant_with_filters() {
let p1: PacmanEvent = "[2019-01-01 00:00] [ALPM] installed a (1.0.0)"
.parse()
.unwrap();
let p2: PacmanEvent = "[2019-01-01 00:00] [ALPM] installed b (1.0.0)"
.parse()
.unwrap();
let p3: PacmanEvent = "[2019-01-02 00:00] [ALPM] upgraded b (1.0.1)"
.parse()
.unwrap();
let p4: PacmanEvent = "[2019-01-02 00:00] [ALPM] installed c (1.0.0)"
.parse()
.unwrap();

let pacman_events = [p1, p2, p3, p4].to_vec();
let filters = [String::from("a")].to_vec();

let groups = pacman_events.group_relevant(&filters);
assert_eq!(groups.keys().len(), 1)
}
}

0 comments on commit 1c77dd1

Please sign in to comment.