11use std:: io;
22
3- use hashbrown :: HashMap ;
3+ use anyhow :: { Context , Result } ;
44use serde:: { Deserialize , Serialize } ;
55use tokio:: sync:: OnceCell ;
6- use yazi_fs :: Xdg ;
7- use yazi_macro :: ok_or_not_found;
6+ use yazi_codegen :: DeserializeOver1 ;
7+ use yazi_fs :: { Xdg , ok_or_not_found} ;
88
99use super :: Service ;
10+ use crate :: { Preset , vfs:: Services } ;
1011
11- #[ derive( Deserialize , Serialize ) ]
12+ #[ derive( Deserialize , Serialize , DeserializeOver1 ) ]
1213pub struct Vfs {
13- pub services : HashMap < String , Service > ,
14+ pub services : Services ,
1415}
1516
1617impl Vfs {
@@ -19,9 +20,10 @@ impl Vfs {
1920
2021 async fn init ( ) -> io:: Result < Vfs > {
2122 tokio:: task:: spawn_blocking ( || {
22- toml:: from_str :: < Vfs > ( & Vfs :: read ( ) ?) . map_err ( io :: Error :: other ) ?. reshape ( )
23+ Preset :: vfs ( ) ? . deserialize_over ( toml:: Deserializer :: parse ( & Vfs :: read ( ) ?) ? ) ?. reshape ( )
2324 } )
2425 . await ?
26+ . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e) )
2527 }
2628
2729 LOADED . get_or_try_init ( init) . await
@@ -40,24 +42,11 @@ impl Vfs {
4042 }
4143 }
4244
43- fn read ( ) -> io :: Result < String > {
45+ fn read ( ) -> Result < String > {
4446 let p = Xdg :: config_dir ( ) . join ( "vfs.toml" ) ;
45- Ok ( ok_or_not_found ! ( std:: fs:: read_to_string( & p) . map_err( |e| {
46- std:: io:: Error :: new( e. kind( ) , format!( "Failed to read VFS config {p:?}: {e}" ) )
47- } ) ) )
47+ ok_or_not_found ( std:: fs:: read_to_string ( & p) )
48+ . with_context ( || format ! ( "Failed to read config {p:?}" ) )
4849 }
4950
50- fn reshape ( mut self ) -> io:: Result < Self > {
51- for ( name, service) in & mut self . services {
52- if name. is_empty ( ) || name. len ( ) > 20 {
53- Err ( io:: Error :: other ( format ! ( "VFS name `{name}` must be between 1 and 20 characters" ) ) ) ?;
54- } else if !name. bytes ( ) . all ( |b| matches ! ( b, b'0' ..=b'9' | b'a' ..=b'z' | b'-' ) ) {
55- Err ( io:: Error :: other ( format ! ( "VFS name `{name}` must be in kebab-case" ) ) ) ?;
56- }
57-
58- service. reshape ( ) ?;
59- }
60-
61- Ok ( self )
62- }
51+ fn reshape ( self ) -> Result < Self > { Ok ( Self { services : self . services . reshape ( ) ? } ) }
6352}
0 commit comments