@@ -10,13 +10,56 @@ use lightning::util::persist::{
1010use std:: fs;
1111use std:: path:: PathBuf ;
1212use std:: time:: UNIX_EPOCH ;
13+ use std:: { error, fmt, io} ;
1314
1415#[ cfg( feature = "tokio" ) ]
1516use core:: future:: Future ;
1617#[ cfg( feature = "tokio" ) ]
1718use lightning:: util:: persist:: { KVStore , PaginatedKVStore } ;
1819use std:: sync:: Arc ;
1920
21+ /// An error returned when constructing a [`FilesystemStoreV2`].
22+ #[ derive( Debug ) ]
23+ pub enum FilesystemStoreV2Error {
24+ /// The data directory contains a file at the top level, indicating it was previously used
25+ /// by [`FilesystemStore`] (v1). Contains the path of the offending file.
26+ ///
27+ /// [`FilesystemStore`]: crate::fs_store::v1::FilesystemStore
28+ V1DataDetected ( PathBuf ) ,
29+ /// An I/O error occurred while inspecting the data directory.
30+ Io ( io:: Error ) ,
31+ }
32+
33+ impl fmt:: Display for FilesystemStoreV2Error {
34+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
35+ match self {
36+ Self :: V1DataDetected ( path) => write ! (
37+ f,
38+ "Found file `{}` in the top-level data directory. \
39+ This indicates the directory was previously used by FilesystemStore (v1). \
40+ Please migrate your data or use a different directory.",
41+ path. display( )
42+ ) ,
43+ Self :: Io ( err) => write ! ( f, "{}" , err) ,
44+ }
45+ }
46+ }
47+
48+ impl error:: Error for FilesystemStoreV2Error {
49+ fn source ( & self ) -> Option < & ( dyn error:: Error + ' static ) > {
50+ match self {
51+ Self :: V1DataDetected ( _) => None ,
52+ Self :: Io ( err) => Some ( err) ,
53+ }
54+ }
55+ }
56+
57+ impl From < io:: Error > for FilesystemStoreV2Error {
58+ fn from ( err : io:: Error ) -> Self {
59+ Self :: Io ( err)
60+ }
61+ }
62+
2063/// A [`KVStore`] and [`KVStoreSync`] implementation that writes to and reads from the file system.
2164///
2265/// This is version 2 of the filesystem store which provides:
@@ -53,25 +96,18 @@ pub struct FilesystemStoreV2 {
5396impl FilesystemStoreV2 {
5497 /// Constructs a new [`FilesystemStoreV2`].
5598 ///
56- /// Returns an error if the data directory already exists and contains files at the top level,
57- /// which would indicate it was previously used by a [`FilesystemStore`] (v1). The v2 store
58- /// expects only directories (namespaces) at the top level.
99+ /// Returns [`FilesystemStoreV2Error::V1DataDetected`] if the data directory already exists
100+ /// and contains files at the top level, which would indicate it was previously used by a
101+ /// [`FilesystemStore`] (v1). The v2 store expects only directories (namespaces) at the top
102+ /// level.
59103 ///
60104 /// [`FilesystemStore`]: crate::fs_store::v1::FilesystemStore
61- pub fn new ( data_dir : PathBuf ) -> std :: io :: Result < Self > {
105+ pub fn new ( data_dir : PathBuf ) -> Result < Self , FilesystemStoreV2Error > {
62106 if data_dir. exists ( ) {
63107 for entry in fs:: read_dir ( & data_dir) ? {
64108 let entry = entry?;
65109 if entry. file_type ( ) ?. is_file ( ) {
66- return Err ( std:: io:: Error :: new (
67- std:: io:: ErrorKind :: InvalidData ,
68- format ! (
69- "Found file `{}` in the top-level data directory. \
70- This indicates the directory was previously used by FilesystemStore (v1). \
71- Please migrate your data or use a different directory.",
72- entry. path( ) . display( )
73- ) ,
74- ) ) ;
110+ return Err ( FilesystemStoreV2Error :: V1DataDetected ( entry. path ( ) ) ) ;
75111 }
76112 }
77113 }
@@ -667,10 +703,10 @@ mod tests {
667703
668704 // V2 construction should fail
669705 match FilesystemStoreV2 :: new ( temp_path. clone ( ) ) {
670- Err ( err) => {
671- assert_eq ! ( err. kind( ) , std:: io:: ErrorKind :: InvalidData ) ;
672- assert ! ( err. to_string( ) . contains( "FilesystemStore (v1)" ) ) ;
706+ Err ( FilesystemStoreV2Error :: V1DataDetected ( path) ) => {
707+ assert_eq ! ( path, temp_path. join( "some_key" ) ) ;
673708 } ,
709+ Err ( err) => panic ! ( "Expected V1DataDetected, got {:?}" , err) ,
674710 Ok ( _) => panic ! ( "Expected error for directory with top-level files" ) ,
675711 }
676712
0 commit comments