1
1
use clap:: Parser ;
2
- use server:: ServerError ;
2
+ use container_type:: ContainerType ;
3
+ use ron:: de:: SpannedError ;
4
+ use serde:: { Deserialize , Serialize } ;
5
+ use std:: error:: Error ;
6
+ use std:: fmt:: Display ;
3
7
use std:: { env, fs, io} ;
4
8
5
9
use std:: { fs:: read_to_string, path:: Path } ;
6
10
11
+ mod container_type;
7
12
mod desktop_entry;
8
13
mod server;
9
14
@@ -13,150 +18,66 @@ mod server;
13
18
struct Args {
14
19
#[ arg( short, long, requires = "server" , value_name = "CONFIG_PATH" ) ]
15
20
/// [AS SERVER] Path to an alternate config for the program.
16
- /// Default is $HOME/.config/container-desktop-entries/containers.conf
21
+ /// Default is $HOME/.config/container-desktop-entries/containers.ron
17
22
config : Option < String > ,
18
23
}
19
24
20
- #[ derive( Debug , Clone , Copy ) ]
21
- enum ContainerType {
22
- Podman ,
23
- Docker ,
24
- Toolbox ,
25
- Unknown ,
25
+ #[ derive( Debug , Clone , Deserialize , Serialize ) ]
26
+ struct ContainerList {
27
+ pub containers : Vec < ( String , ContainerType ) > ,
26
28
}
27
29
28
- impl From < String > for ContainerType {
29
- fn from ( value : String ) -> Self {
30
- match value. as_str ( ) {
31
- "toolbox" => ContainerType :: Toolbox ,
32
- "docker" => ContainerType :: Docker ,
33
- "podman" => ContainerType :: Podman ,
34
- _ => ContainerType :: Unknown ,
35
- }
36
- }
37
- }
38
- impl From < ContainerType > for String {
39
- fn from ( value : ContainerType ) -> Self {
40
- match value {
41
- ContainerType :: Toolbox => "toolbox" . to_string ( ) ,
42
- ContainerType :: Docker => "docker" . to_string ( ) ,
43
- ContainerType :: Podman => "podman" . to_string ( ) ,
44
- ContainerType :: Unknown => "" . to_string ( ) ,
45
- }
46
- }
30
+ #[ derive( Debug ) ]
31
+ enum CDEError {
32
+ IO ( io:: Error ) ,
33
+ NoEnv ( std:: env:: VarError ) ,
34
+ Ron ( SpannedError ) ,
47
35
}
48
36
49
- impl ContainerType {
50
- fn not_supported ( self ) -> bool {
51
- matches ! (
52
- self ,
53
- ContainerType :: Docker | ContainerType :: Podman | ContainerType :: Unknown
54
- )
55
- }
56
-
57
- fn format_copy ( self , container_name : & str , from : & Path , to : & Path ) -> String {
58
- match self {
59
- ContainerType :: Toolbox => {
60
- format ! (
61
- "podman container cp {}:{}/. {}/" ,
62
- container_name,
63
- from. to_str( ) . unwrap( ) ,
64
- to. to_str( ) . unwrap( )
65
- )
66
- }
67
- _ => "" . to_string ( ) , // TODO: Support more container types
68
- }
69
- }
70
-
71
- fn format_exec ( self , container_name : & str , command : & str ) -> String {
72
- match self {
73
- ContainerType :: Toolbox => {
74
- format ! ( "toolbox run -c {} {}" , container_name, command)
75
- }
76
- _ => "" . to_string ( ) , // TODO: Support more container types
77
- }
37
+ impl Error for CDEError {
38
+ fn source ( & self ) -> Option < & ( dyn Error + ' static ) > {
39
+ None
78
40
}
79
41
80
- fn format_exec_regex_pattern ( self ) -> String {
81
- match self {
82
- ContainerType :: Toolbox | ContainerType :: Podman | ContainerType :: Docker => {
83
- r"(Exec=\s?)(.*)" . to_string ( )
84
- }
85
- _ => "" . to_string ( ) ,
86
- }
42
+ fn description ( & self ) -> & str {
43
+ "description() is deprecated; use Display"
87
44
}
88
45
89
- fn format_desktop_exec ( self , container_name : & str ) -> String {
90
- match self {
91
- ContainerType :: Toolbox => {
92
- format ! ( r"Exec=toolbox run -c {} ${{2}}" , container_name)
93
- }
94
- ContainerType :: Podman => {
95
- // TODO: Currently not always functional
96
- format ! (
97
- r"Exec=sh -c 'podman container start {} && podman container exec {} ${{2}}'" ,
98
- container_name, container_name
99
- )
100
- }
101
- _ => "" . to_string ( ) , // TODO: Support more container types
102
- }
103
- }
104
-
105
- fn format_name_regex_pattern ( self ) -> String {
106
- match self {
107
- ContainerType :: Toolbox | ContainerType :: Podman | ContainerType :: Docker => {
108
- r"(Name=\s?)(.*)" . to_string ( )
109
- }
110
- _ => "" . to_string ( ) ,
111
- }
112
- }
113
-
114
- fn format_desktop_name ( self , container_name : & str ) -> String {
115
- match self {
116
- ContainerType :: Toolbox => {
117
- format ! ( r"Name=${{2}} ({})" , container_name)
118
- }
119
- _ => "" . to_string ( ) , // TODO: Support more container types
120
- }
46
+ fn cause ( & self ) -> Option < & dyn Error > {
47
+ self . source ( )
121
48
}
49
+ }
122
50
123
- fn format_start ( self , container_name : & str ) -> String {
51
+ impl Display for CDEError {
52
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
124
53
match self {
125
- ContainerType :: Toolbox => {
126
- format ! ( "toolbox run -c {} echo 'Started'" , container_name)
127
- }
128
- _ => "" . to_string ( ) , // TODO: Support more container types
54
+ Self :: IO ( e) => e. fmt ( f) ,
55
+ Self :: NoEnv ( e) => e. fmt ( f) ,
56
+ Self :: Ron ( e) => e. fmt ( f) ,
129
57
}
130
58
}
131
59
}
132
60
133
- #[ derive( Debug ) ]
134
- enum Error {
135
- Server ( ServerError ) ,
136
- IO ( io:: Error ) ,
137
- NoEnv ( std:: env:: VarError ) ,
138
- }
139
-
140
- impl From < ServerError > for Error {
141
- fn from ( value : ServerError ) -> Self {
142
- Error :: Server ( value)
61
+ impl From < io:: Error > for CDEError {
62
+ fn from ( value : io:: Error ) -> Self {
63
+ Self :: IO ( value)
143
64
}
144
65
}
145
66
146
- impl From < io :: Error > for Error {
147
- fn from ( value : io :: Error ) -> Self {
148
- Error :: IO ( value)
67
+ impl From < std :: env :: VarError > for CDEError {
68
+ fn from ( value : std :: env :: VarError ) -> Self {
69
+ Self :: NoEnv ( value)
149
70
}
150
71
}
151
72
152
- impl From < std :: env :: VarError > for Error {
153
- fn from ( value : std :: env :: VarError ) -> Self {
154
- Error :: NoEnv ( value)
73
+ impl From < SpannedError > for CDEError {
74
+ fn from ( value : SpannedError ) -> Self {
75
+ Self :: Ron ( value)
155
76
}
156
77
}
157
78
158
79
#[ async_std:: main]
159
- async fn main ( ) -> Result < ( ) , Error > {
80
+ async fn main ( ) -> Result < ( ) , CDEError > {
160
81
env_logger:: init ( ) ;
161
82
162
83
if !cfg ! ( target_os = "linux" ) {
@@ -167,7 +88,7 @@ async fn main() -> Result<(), Error> {
167
88
let args = Args :: parse ( ) ;
168
89
169
90
let default_path_str = format ! (
170
- "{}/.config/container-desktop-entries/containers.conf " ,
91
+ "{}/.config/container-desktop-entries/containers.ron " ,
171
92
env:: var( "HOME" ) ?
172
93
) ;
173
94
let conf_path = match args. config . as_ref ( ) {
@@ -181,18 +102,9 @@ async fn main() -> Result<(), Error> {
181
102
}
182
103
_ => { }
183
104
}
184
- log:: info!( "Running as server! Getting config at '{:?}'" , conf_path) ;
185
- let config_data = read_to_string ( conf_path) ?
186
- . lines ( )
187
- . map ( |s| {
188
- let ss = s
189
- . split_once ( " " )
190
- . expect ( "Config invalid. make sure all lines are <<NAME>> <<TYPE>>" ) ;
191
- ( ss. 0 . to_string ( ) , ContainerType :: from ( ss. 1 . to_string ( ) ) )
192
- } )
193
- . collect :: < Vec < _ > > ( ) ;
194
-
195
- server:: server ( config_data) . await ?;
105
+ let config_data: ContainerList = ron:: from_str ( & read_to_string ( conf_path) ?) ?;
106
+
107
+ server:: server ( config_data) . await ;
196
108
197
109
Ok ( ( ) )
198
110
}
0 commit comments