Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow filtering based on Store/root type #329

Closed
wants to merge 12 commits into from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
/tmp
tests/root3/game5/data-symlink
*~
.idea/
45 changes: 28 additions & 17 deletions src/cli/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ mod tests {

use super::*;
use crate::{
resource::manifest::Store,
scan::{registry_compat::RegistryItem, ScannedFile, ScannedRegistry},
testing::s,
};
Expand Down Expand Up @@ -598,6 +599,7 @@ Overall:
change: Default::default(),
container: None,
redirected: None,
store: None,
},
ScannedFile {
path: StrictPath::new(s("/file2")),
Expand All @@ -608,6 +610,7 @@ Overall:
change: Default::default(),
container: None,
redirected: None,
store: None,
},
},
found_registry_keys: hash_set! {
Expand All @@ -619,7 +622,7 @@ Overall:
},
&BackupInfo {
failed_files: hash_set! {
ScannedFile::new("/file2", 51_200, "2"),
ScannedFile::new("/file2", 51_200, "2", None),
},
failed_registry: hash_set! {
RegistryItem::new(s("HKEY_CURRENT_USER/Key1"))
Expand Down Expand Up @@ -667,6 +670,7 @@ Overall:
change: ScanChange::Same,
container: None,
redirected: None,
store: None,
},
},
found_registry_keys: hash_set! {},
Expand All @@ -693,6 +697,7 @@ Overall:
change: Default::default(),
container: None,
redirected: None,
store: None,
},
},
found_registry_keys: hash_set! {},
Expand Down Expand Up @@ -742,6 +747,7 @@ Overall:
change: Default::default(),
container: None,
redirected: None,
store: None,
},
ScannedFile {
path: StrictPath::new(format!("{}/backup/file2", drive())),
Expand All @@ -752,6 +758,7 @@ Overall:
change: Default::default(),
container: None,
redirected: None,
store: None,
},
},
found_registry_keys: hash_set! {},
Expand Down Expand Up @@ -788,7 +795,7 @@ Overall:
&ScanInfo {
game_name: s(name),
found_files: hash_set! {
ScannedFile::new("/file1", 102_400, "1").change_as(ScanChange::New),
ScannedFile::new("/file1", 102_400, "1", None).change_as(ScanChange::New),
},
found_registry_keys: hash_set! {
ScannedRegistry::new("HKEY_CURRENT_USER/Key1").change_as(ScanChange::New),
Expand All @@ -804,7 +811,7 @@ Overall:
&ScanInfo {
game_name: s("foo"),
found_files: hash_set! {
ScannedFile::new("/file1", 102_400, "1"),
ScannedFile::new("/file1", 102_400, "1", None),
},
found_registry_keys: hash_set! {
ScannedRegistry::new("HKEY_CURRENT_USER/Key1"),
Expand Down Expand Up @@ -835,16 +842,17 @@ Overall:
#[test]
fn can_render_in_standard_mode_with_different_file_changes() {
let mut reporter = Reporter::standard();
let store = Option::<Store>::None;

reporter.add_game(
"foo",
&ScanInfo {
game_name: s("foo"),
found_files: hash_set! {
ScannedFile::new(s("/new"), 1, "1".to_string()).change_as(ScanChange::New),
ScannedFile::new(s("/different"), 1, "1".to_string()).change_as(ScanChange::Different),
ScannedFile::new(s("/same"), 1, "1".to_string()).change_as(ScanChange::Same),
ScannedFile::new(s("/unknown"), 1, "1".to_string()).change_as(ScanChange::Unknown),
ScannedFile::new(s("/new"), 1, "1".to_string(), store).change_as(ScanChange::New),
ScannedFile::new(s("/different"), 1, "1".to_string(), store).change_as(ScanChange::Different),
ScannedFile::new(s("/same"), 1, "1".to_string(), store).change_as(ScanChange::Same),
ScannedFile::new(s("/unknown"), 1, "1".to_string(), store).change_as(ScanChange::Unknown),
},
found_registry_keys: hash_set! {},
..Default::default()
Expand All @@ -861,7 +869,7 @@ Overall:
&ScanInfo {
game_name: s("bar"),
found_files: hash_set! {
ScannedFile::new(s("/brand-new"), 1, "1".to_string()).change_as(ScanChange::New),
ScannedFile::new(s("/brand-new"), 1, "1".to_string(), None).change_as(ScanChange::New),
},
found_registry_keys: hash_set! {},
..Default::default()
Expand Down Expand Up @@ -937,8 +945,8 @@ Overall:
&ScanInfo {
game_name: s("foo"),
found_files: hash_set! {
ScannedFile::new("/file1", 100, "1"),
ScannedFile::new("/file2", 50, "2"),
ScannedFile::new("/file1", 100, "1", None),
ScannedFile::new("/file2", 50, "2", None),
},
found_registry_keys: hash_set! {
ScannedRegistry::new("HKEY_CURRENT_USER/Key1"),
Expand All @@ -949,7 +957,7 @@ Overall:
},
&BackupInfo {
failed_files: hash_set! {
ScannedFile::new("/file2", 50, "2"),
ScannedFile::new("/file2", 50, "2", None),
},
failed_registry: hash_set! {
RegistryItem::new(s("HKEY_CURRENT_USER/Key1"))
Expand Down Expand Up @@ -1035,6 +1043,7 @@ Overall:
change: Default::default(),
container: None,
redirected: None,
store: None,
},
ScannedFile {
path: StrictPath::new(format!("{}/backup/file2", drive())),
Expand All @@ -1045,6 +1054,7 @@ Overall:
change: Default::default(),
container: None,
redirected: None,
store: None,
},
},
found_registry_keys: hash_set! {},
Expand Down Expand Up @@ -1103,7 +1113,7 @@ Overall:
&ScanInfo {
game_name: s(name),
found_files: hash_set! {
ScannedFile::new("/file1", 102_400, "1"),
ScannedFile::new("/file1", 102_400, "1", None),
},
found_registry_keys: hash_set! {
ScannedRegistry::new("HKEY_CURRENT_USER/Key1"),
Expand All @@ -1119,7 +1129,7 @@ Overall:
&ScanInfo {
game_name: s("foo"),
found_files: hash_set! {
ScannedFile::new("/file1", 100, "2"),
ScannedFile::new("/file1", 100, "2", None),
},
found_registry_keys: hash_set! {
ScannedRegistry::new("HKEY_CURRENT_USER/Key1"),
Expand Down Expand Up @@ -1178,16 +1188,17 @@ Overall:
#[test]
fn can_render_in_json_mode_with_different_file_changes() {
let mut reporter = Reporter::json();
let store = None;

reporter.add_game(
"foo",
&ScanInfo {
game_name: s("foo"),
found_files: hash_set! {
ScannedFile::new("/new", 1, "1").change_as(ScanChange::New),
ScannedFile::new("/different", 1, "2").change_as(ScanChange::Different),
ScannedFile::new("/same", 1, "2").change_as(ScanChange::Same),
ScannedFile::new("/unknown", 1, "2").change_as(ScanChange::Unknown),
ScannedFile::new("/new", 1, "1", store).change_as(ScanChange::New),
ScannedFile::new("/different", 1, "2", store).change_as(ScanChange::Different),
ScannedFile::new("/same", 1, "2", store).change_as(ScanChange::Same),
ScannedFile::new("/unknown", 1, "2", store).change_as(ScanChange::Unknown),
},
found_registry_keys: hash_set! {},
..Default::default()
Expand Down
9 changes: 9 additions & 0 deletions src/gui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1797,6 +1797,15 @@ impl Application for App {
search.change.choice = filter;
Command::none()
}
Message::EditedSearchFilterStore(filter) => {
let search = if self.screen == Screen::Backup {
&mut self.backup_screen.log.search
} else {
&mut self.restore_screen.log.search
};
search.store.choice = filter;
Command::none()
}
Message::EditedSortKey { screen, value } => {
match screen {
Screen::Backup => {
Expand Down
1 change: 1 addition & 0 deletions src/gui/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ pub enum Message {
EditedSearchFilterCompleteness(game_filter::Completeness),
EditedSearchFilterEnablement(game_filter::Enablement),
EditedSearchFilterChange(game_filter::Change),
EditedSearchFilterStore(Store),
EditedSortKey {
screen: Screen,
value: SortKey,
Expand Down
3 changes: 2 additions & 1 deletion src/gui/game_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::{
resource::{
cache::Cache,
config::{Config, Sort},
manifest::{Manifest, Os},
manifest::{Manifest, Os, Store},
},
scan::{layout::GameLayout, BackupInfo, DuplicateDetector, OperationStatus, ScanChange, ScanInfo},
};
Expand All @@ -37,6 +37,7 @@ pub struct GameListEntry {
/// The `scan_info` gets mutated in response to things like toggling saves off,
/// so we need a persistent flag to say if the game has been scanned yet.
pub scanned: bool,
pub store: Option<Store>,
}

impl GameListEntry {
Expand Down
6 changes: 5 additions & 1 deletion src/gui/screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ fn make_status_row<'a>(status: &OperationStatus, duplication: Duplication) -> Ro
.push(text(TRANSLATOR.processed_games(status)).size(size))
.push_if(
|| status.changed_games.new > 0,
|| Badge::new_entry_with_count(status.changed_games.new).view(),
|| {
Badge::new_entry_with_count(status.changed_games.new)
.on_press(Message::EditedSearchFilterChange(crate::scan::game_filter::Change::New))
.view()
},
)
.push_if(
|| status.changed_games.different > 0,
Expand Down
12 changes: 11 additions & 1 deletion src/gui/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
widget::{checkbox, pick_list, text, Column, Element, IcedParentExt, Row},
},
lang::TRANSLATOR,
resource::manifest::Store,
scan::{
game_filter::{self, FilterKind},
Duplication, ScanInfo,
Expand All @@ -28,6 +29,7 @@ pub struct FilterComponent {
pub completeness: Filter<game_filter::Completeness>,
pub enablement: Filter<game_filter::Enablement>,
pub change: Filter<game_filter::Change>,
pub store: Filter<crate::resource::manifest::Store>,
}

fn template<'a, T: 'static + Default + Copy + Eq + PartialEq + ToString>(
Expand Down Expand Up @@ -66,8 +68,9 @@ impl FilterComponent {
let complete = !self.completeness.active || self.completeness.choice.qualifies(scan);
let enable = !show_deselected_games || !self.enablement.active || self.enablement.choice.qualifies(enabled);
let changed = !self.change.active || self.change.choice.qualifies(scan);
let store = !self.store.active || self.store.choice.qualifies(scan);

fuzzy && unique && complete && changed && enable
fuzzy && unique && complete && changed && store && enable
}

pub fn toggle_filter(&mut self, filter: FilterKind, enabled: bool) {
Expand All @@ -76,6 +79,7 @@ impl FilterComponent {
FilterKind::Completeness => self.completeness.active = enabled,
FilterKind::Enablement => self.enablement.active = enabled,
FilterKind::Change => self.change.active = enabled,
FilterKind::Store => self.store.active = enabled,
}
}

Expand Down Expand Up @@ -119,6 +123,12 @@ impl FilterComponent {
game_filter::Change::ALL,
Message::EditedSearchFilterChange,
))
.push(template(
&self.store,
FilterKind::Store,
Store::ALL,
Message::EditedSearchFilterStore,
))
.push_if(
|| show_deselected_games,
|| {
Expand Down
34 changes: 33 additions & 1 deletion src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use once_cell::sync::Lazy;

use crate::{
prelude::{AnyError, SKIP},
resource::manifest::Os,
resource::manifest::{Os, Store},
};

#[cfg(target_os = "windows")]
Expand Down Expand Up @@ -275,6 +275,38 @@ pub fn resolve(raw: impl Into<String>) -> Result<String, StrictPathError> {
Ok(path)
}

/// Stores metadata related to the path.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct PathMetadata {
is_case_sensitive: bool,
store: Option<Store>,
}

impl PathMetadata {
pub fn new(is_case_sensitive: bool, store: Option<Store>) -> Self {
PathMetadata {
is_case_sensitive,
store,
}
}

pub fn is_case_sensitive(&self) -> bool {
self.is_case_sensitive
}

#[allow(dead_code)]
pub fn store(&self) -> Option<Store> {
self.store
}
Comment on lines +293 to +300
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having methods for these, we can just make the fields pub.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_case_sensitive is from your code, just to be clear. But I have no issue doing that refactor.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what you mean; this is part of the new PathMetadata struct introduced in this PR. Previously, this was just a loose bool in fn parse_paths.

}

impl std::hash::Hash for PathMetadata {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.is_case_sensitive.hash(state);
self.store.hash(state);
}
}
Comment on lines +303 to +308
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to derive this.


/// This is a wrapper around paths to make it more obvious when we're
/// converting between different representations. This also handles
/// things like `~`.
Expand Down
Loading