@@ -5,6 +5,8 @@ use std::{fs, io::Write, path::Path};
55pub ( crate ) const CLOSE_ACTION_TRAY : & str = "tray" ;
66pub ( crate ) const CLOSE_ACTION_EXIT : & str = "exit" ;
77
8+ type Logger < ' a > = dyn Fn ( & str ) + ' a ;
9+
810#[ derive( Debug , Clone , Copy , PartialEq , Eq , Serialize , Deserialize ) ]
911#[ serde( rename_all = "lowercase" ) ]
1012pub ( crate ) enum CloseAction {
@@ -52,10 +54,7 @@ pub(crate) fn parse_close_action(raw: &str) -> Option<CloseAction> {
5254 }
5355}
5456
55- fn load_desktop_state < F > ( raw : & str , log_subject : & str , log : & F ) -> DesktopState
56- where
57- F : Fn ( & str ) ,
58- {
57+ fn load_desktop_state ( raw : & str , log_subject : & str , log : & Logger < ' _ > ) -> DesktopState {
5958 match serde_json:: from_str :: < DesktopState > ( raw) {
6059 Ok ( state) => state,
6160 Err ( error) => {
@@ -78,28 +77,25 @@ where
7877 read_cached_close_action_at_path ( & state_path, & log)
7978}
8079
81- fn read_cached_close_action_at_path < F > ( state_path : & Path , log : & F ) -> Option < CloseAction >
82- where
83- F : Fn ( & str ) ,
84- {
80+ fn read_cached_close_action_at_path ( state_path : & Path , log : & Logger < ' _ > ) -> Option < CloseAction > {
8581 let raw = fs:: read_to_string ( state_path) . ok ( ) ?;
8682 let state = load_desktop_state ( & raw , "desktop close behavior state" , log) ;
8783 state. close_action
8884}
8985
90- fn save_desktop_state ( path : & Path , state : & DesktopState ) -> Result < ( ) , String > {
86+ fn atomic_write_json ( path : & Path , value : & impl Serialize , what : & str ) -> Result < ( ) , String > {
9187 if let Some ( parent_dir) = path. parent ( ) {
9288 fs:: create_dir_all ( parent_dir) . map_err ( |error| {
9389 format ! (
94- "Failed to create close behavior directory {}: {}" ,
90+ "Failed to create {what} directory {}: {}" ,
9591 parent_dir. display( ) ,
9692 error
9793 )
9894 } ) ?;
9995 }
10096
101- let serialized = serde_json:: to_string_pretty ( state )
102- . map_err ( |error| format ! ( "Failed to serialize close behavior state : {error}" ) ) ?;
97+ let serialized = serde_json:: to_string_pretty ( value )
98+ . map_err ( |error| format ! ( "Failed to serialize {what} : {error}" ) ) ?;
10399 let tmp_name = format ! (
104100 "{}.tmp" ,
105101 path. file_name( )
@@ -110,7 +106,7 @@ fn save_desktop_state(path: &Path, state: &DesktopState) -> Result<(), String> {
110106
111107 let mut file = fs:: File :: create ( & tmp_path) . map_err ( |error| {
112108 format ! (
113- "Failed to create temporary close behavior state file {}: {}" ,
109+ "Failed to create temporary {what} file {}: {}" ,
114110 tmp_path. display( ) ,
115111 error
116112 )
@@ -119,20 +115,24 @@ fn save_desktop_state(path: &Path, state: &DesktopState) -> Result<(), String> {
119115 . and_then ( |_| file. sync_all ( ) )
120116 . map_err ( |error| {
121117 format ! (
122- "Failed to write temporary close behavior state file {}: {}" ,
118+ "Failed to write temporary {what} file {}: {}" ,
123119 tmp_path. display( ) ,
124120 error
125121 )
126122 } ) ?;
127123 fs:: rename ( & tmp_path, path) . map_err ( |error| {
128124 format ! (
129- "Failed to atomically replace close behavior state file {}: {}" ,
125+ "Failed to atomically replace {what} file {}: {}" ,
130126 path. display( ) ,
131127 error
132128 )
133129 } )
134130}
135131
132+ fn save_desktop_state ( path : & Path , state : & DesktopState ) -> Result < ( ) , String > {
133+ atomic_write_json ( path, state, "close behavior state" )
134+ }
135+
136136pub ( crate ) fn write_cached_close_action < F > (
137137 action : Option < CloseAction > ,
138138 packaged_root_dir : Option < & Path > ,
@@ -150,14 +150,11 @@ where
150150 write_cached_close_action_at_path ( action, & state_path, & log)
151151}
152152
153- fn write_cached_close_action_at_path < F > (
153+ fn write_cached_close_action_at_path (
154154 action : Option < CloseAction > ,
155155 state_path : & Path ,
156- log : & F ,
157- ) -> Result < ( ) , String >
158- where
159- F : Fn ( & str ) ,
160- {
156+ log : & Logger < ' _ > ,
157+ ) -> Result < ( ) , String > {
161158 let mut state = match fs:: read_to_string ( state_path) {
162159 Ok ( raw) => load_desktop_state (
163160 & raw ,
0 commit comments