1+ use std:: collections:: HashSet ;
2+
13use clap:: { Command , arg} ;
4+ use inquire:: MultiSelect ;
25use miette:: { IntoDiagnostic , Result } ;
3- use tracing:: { Level , info} ;
6+ use tracing:: { Level , debug , info} ;
47use tracing_subscriber:: EnvFilter ;
5- use winapps:: { Config , Freerdp , RemoteClient } ;
8+ use winapps:: { Config , Freerdp , RemoteClient , config :: App } ;
69
710fn cli ( ) -> Command {
811 Command :: new ( "winapps-cli" )
@@ -26,8 +29,6 @@ fn cli() -> Command {
2629
2730fn main ( ) -> Result < ( ) > {
2831 tracing_subscriber:: fmt ( )
29- . without_time ( )
30- . with_target ( false )
3132 . with_level ( true )
3233 . with_max_level ( Level :: INFO )
3334 . with_env_filter ( EnvFilter :: from_default_env ( ) )
@@ -45,16 +46,41 @@ fn main() -> Result<()> {
4546 Some ( ( "setup" , _) ) => {
4647 info ! ( "Running setup" ) ;
4748
48- // TODO: Allow deleting apps, maybe pass installed apps
49- // so they can be deselected?
50- match inquire:: MultiSelect :: new ( "Select apps to link" , config. get_available_apps ( ) ?)
49+ let available = config. get_available_apps ( ) ?;
50+ let installed: Vec < usize > = available
51+ . iter ( )
52+ . enumerate ( )
53+ . filter_map ( |( i, app) | config. linked_apps . contains_key ( & app. id ) . then_some ( i) )
54+ . collect ( ) ;
55+
56+ debug ! (
57+ "{} apps available, {} apps installed" ,
58+ available. len( ) ,
59+ config. linked_apps. len( )
60+ ) ;
61+
62+ match MultiSelect :: new ( "Select apps to link" , available)
63+ . with_default ( installed. as_slice ( ) )
64+ . with_page_size ( 20 )
5165 . prompt_skippable ( )
5266 . map_err ( |e| winapps:: Error :: Command {
5367 message : "Failed to display selection dialog" . into ( ) ,
5468 source : e. into ( ) ,
5569 } ) ? {
56- Some ( apps) => apps. into_iter ( ) . try_for_each ( |app| app. link ( & mut config) ) ?,
57- None => info ! ( "No apps selected, skipping setup..." ) ,
70+ Some ( apps) => {
71+ let selected: HashSet < App > = apps. into_iter ( ) . collect ( ) ;
72+ let installed: HashSet < App > = config. linked_apps . values ( ) . cloned ( ) . collect ( ) ;
73+
74+ for app in selected. symmetric_difference ( & installed) . cloned ( ) {
75+ match ( selected. contains ( & app) , installed. contains ( & app) ) {
76+ ( true , false ) => app. link ( & mut config) ?,
77+ ( false , true ) => app. unlink ( & mut config) ?,
78+ ( false , false ) => ( ) ,
79+ ( true , true ) => unreachable ! ( ) ,
80+ }
81+ }
82+ }
83+ None => info ! ( "No apps (de-)selected, skipping setup..." ) ,
5884 } ;
5985
6086 Ok ( ( ) )
0 commit comments