rename all crates

This commit is contained in:
steven-omaha
2023-02-14 13:12:08 +01:00
parent c7841ae346
commit e7cb7d9321
42 changed files with 119 additions and 93 deletions
@@ -0,0 +1,56 @@
use std::rc::Rc;
use crate::backend::Backend;
use crate::{Group, Package};
#[derive(Debug, PartialEq)]
pub(super) enum ReviewAction {
AsDependency(Package),
Delete(Package),
AssignGroup(Package, Rc<Group>),
}
#[derive(Debug)]
pub(super) enum ReviewIntention {
AsDependency,
AssignGroup,
Delete,
Info,
Invalid,
Skip,
Quit,
}
#[derive(Debug)]
pub(super) struct ReviewsPerBackend {
items: Vec<(Box<dyn Backend>, Vec<ReviewAction>)>,
}
impl ReviewsPerBackend {
pub(super) fn new() -> Self {
Self { items: vec![] }
}
pub(super) fn nothing_to_do(&self) -> bool {
self.items.iter().all(|(_, vec)| vec.is_empty())
}
pub(super) fn push(&mut self, value: (Box<dyn Backend>, Vec<ReviewAction>)) {
self.items.push(value);
}
}
impl IntoIterator for ReviewsPerBackend {
type Item = (Box<dyn Backend>, Vec<ReviewAction>);
type IntoIter = std::vec::IntoIter<(Box<dyn Backend>, Vec<ReviewAction>)>;
fn into_iter(self) -> Self::IntoIter {
self.items.into_iter()
}
}
pub(super) enum ContinueWithReview {
Yes,
No,
}
+134
View File
@@ -0,0 +1,134 @@
mod datastructures;
mod strategy;
use std::io::{stdin, stdout, Write};
use std::rc::Rc;
use anyhow::Result;
use crate::backend::{Backend, ToDoPerBackend};
use crate::ui::{get_user_confirmation, read_single_char_from_terminal};
use crate::{Group, Package};
use self::datastructures::{ContinueWithReview, ReviewAction, ReviewIntention, ReviewsPerBackend};
use self::strategy::Strategy;
pub fn review(
todo_per_backend: ToDoPerBackend,
groups: impl IntoIterator<Item = Group>,
) -> Result<()> {
let mut reviews = ReviewsPerBackend::new();
let mut groups: Vec<Rc<Group>> = groups.into_iter().map(Rc::new).collect();
groups.sort_unstable();
if todo_per_backend.nothing_to_do_for_all_backends() {
println!("nothing to do");
return Ok(());
}
for (backend, packages) in todo_per_backend.into_iter() {
let mut actions = vec![];
for package in packages {
println!("{}: {package}", backend.get_section());
match get_action_for_package(package, &groups, &mut actions, &*backend)? {
ContinueWithReview::Yes => continue,
ContinueWithReview::No => return Ok(()),
}
}
reviews.push((backend, actions));
}
if reviews.nothing_to_do() {
println!("nothing to do");
return Ok(());
}
let strategies: Vec<Strategy> = reviews.into();
for strat in &strategies {
strat.show();
}
if !get_user_confirmation()? {
return Ok(());
}
for strat in strategies {
strat.execute()?;
}
Ok(())
}
fn get_action_for_package(
package: Package,
groups: &[Rc<Group>],
reviews: &mut Vec<ReviewAction>,
backend: &dyn Backend,
) -> Result<ContinueWithReview> {
loop {
match ask_user_action_for_package()? {
ReviewIntention::AsDependency => {
reviews.push(ReviewAction::AsDependency(package));
break;
}
ReviewIntention::AssignGroup => {
if let Ok(Some(group)) = ask_group(groups) {
reviews.push(ReviewAction::AssignGroup(package, group));
break;
};
}
ReviewIntention::Delete => {
reviews.push(ReviewAction::Delete(package));
break;
}
ReviewIntention::Info => {
backend.show_package_info(&package)?;
}
ReviewIntention::Invalid => (),
ReviewIntention::Skip => break,
ReviewIntention::Quit => return Ok(ContinueWithReview::No),
}
}
Ok(ContinueWithReview::Yes)
}
fn ask_user_action_for_package() -> Result<ReviewIntention> {
print!("assign to (g)roup, (d)elete, (s)kip, (i)nfo, (a)s dependency, (q)uit? ");
stdout().lock().flush()?;
match read_single_char_from_terminal()? {
'a' => Ok(ReviewIntention::AsDependency),
'd' => Ok(ReviewIntention::Delete),
'g' => Ok(ReviewIntention::AssignGroup),
'i' => Ok(ReviewIntention::Info),
'q' => Ok(ReviewIntention::Quit),
's' => Ok(ReviewIntention::Skip),
_ => Ok(ReviewIntention::Invalid),
}
}
fn print_enumerated_groups(groups: &[Rc<Group>]) {
for (i, group) in groups.iter().enumerate() {
println!("{i}: {}", group.name);
}
}
fn ask_group(groups: &[Rc<Group>]) -> Result<Option<Rc<Group>>> {
print_enumerated_groups(groups);
let mut buf = String::new();
stdin().read_line(&mut buf)?;
let reply = buf.trim();
let idx: usize = if let Ok(idx) = reply.parse() {
idx
} else {
return Ok(None);
};
if idx < groups.len() {
Ok(Some(groups[idx].clone()))
} else {
Ok(None)
}
}
+124
View File
@@ -0,0 +1,124 @@
use std::rc::Rc;
use anyhow::Result;
use crate::backend::Backend;
use crate::{Group, Package};
use super::datastructures::{ReviewAction, ReviewsPerBackend};
#[derive(Debug)]
pub(super) struct Strategy {
backend: Box<dyn Backend>,
delete: Vec<Package>,
as_dependency: Vec<Package>,
assign_group: Vec<(Package, Rc<Group>)>,
}
impl Strategy {
pub(super) fn new(
backend: Box<dyn Backend>,
delete: Vec<Package>,
as_dependency: Vec<Package>,
assign_group: Vec<(Package, Rc<Group>)>,
) -> Self {
Self {
backend,
delete,
as_dependency,
assign_group,
}
}
pub(super) fn execute(self) -> Result<()> {
if !self.delete.is_empty() {
self.backend.remove_packages(&self.delete)?;
}
if !self.as_dependency.is_empty() {
self.backend.make_dependency(&self.as_dependency)?;
}
if !self.assign_group.is_empty() {
self.backend.assign_group(self.assign_group)?;
}
Ok(())
}
pub(super) fn show(&self) {
if self.nothing_to_do() {
return;
}
println!("[{}]", self.backend.get_section());
if !self.delete.is_empty() {
println!("delete:");
for p in &self.delete {
println!(" {p}");
}
}
if !self.as_dependency.is_empty() {
println!("as depdendency:");
for p in &self.as_dependency {
println!(" {p}");
}
}
if !self.assign_group.is_empty() {
println!("assign groups:");
for (p, g) in &self.assign_group {
println!(" {p} -> {}", g.name);
}
}
}
pub(super) fn nothing_to_do(&self) -> bool {
self.delete.is_empty() && self.as_dependency.is_empty() && self.assign_group.is_empty()
}
}
impl From<ReviewsPerBackend> for Vec<Strategy> {
fn from(reviews: ReviewsPerBackend) -> Self {
let mut result = vec![];
for (backend, actions) in reviews {
let mut to_delete = vec![];
let mut assign_group = vec![];
let mut as_dependency = vec![];
extract_actions(
actions,
&mut to_delete,
&mut assign_group,
&mut as_dependency,
);
result.push(Strategy::new(
backend,
to_delete,
as_dependency,
assign_group,
));
}
result
}
}
fn extract_actions(
actions: Vec<ReviewAction>,
to_delete: &mut Vec<Package>,
assign_group: &mut Vec<(Package, Rc<Group>)>,
as_dependency: &mut Vec<Package>,
) {
for action in actions {
match action {
ReviewAction::Delete(package) => to_delete.push(package),
ReviewAction::AssignGroup(package, group) => assign_group.push((package, group)),
ReviewAction::AsDependency(package) => as_dependency.push(package),
}
}
}