@@ -22,6 +22,7 @@ use async_trait::async_trait;
2222use bytes:: Bytes ;
2323use opendal:: Operator ;
2424use opendal:: services:: FsConfig ;
25+ use serde:: { Deserialize , Serialize } ;
2526
2627use crate :: Result ;
2728use crate :: io:: {
@@ -37,7 +38,9 @@ pub(crate) fn fs_config_build() -> Result<Operator> {
3738}
3839
3940/// Filesystem storage implementation using OpenDAL
40- #[ derive( Debug , Clone ) ]
41+ ///
42+ /// This storage is stateless and creates operators on-demand.
43+ #[ derive( Debug , Clone , Serialize , Deserialize ) ]
4144pub struct OpenDALFsStorage ;
4245
4346impl OpenDALFsStorage {
@@ -52,6 +55,7 @@ impl OpenDALFsStorage {
5255}
5356
5457#[ async_trait]
58+ #[ typetag:: serde]
5559impl Storage for OpenDALFsStorage {
5660 async fn exists ( & self , path : & str ) -> Result < bool > {
5761 let relative_path = self . extract_relative_path ( path) ;
@@ -131,3 +135,27 @@ impl StorageFactory for OpenDALFsStorageFactory {
131135 Ok ( Arc :: new ( OpenDALFsStorage ) )
132136 }
133137}
138+
139+ #[ cfg( test) ]
140+ mod tests {
141+ use super :: * ;
142+ use crate :: io:: Storage ;
143+
144+ #[ test]
145+ fn test_fs_storage_serialization ( ) {
146+ // Create a filesystem storage instance using the factory
147+ let factory = OpenDALFsStorageFactory ;
148+ let storage = factory
149+ . build ( HashMap :: new ( ) , Extensions :: default ( ) )
150+ . unwrap ( ) ;
151+
152+ // Serialize the storage
153+ let serialized = serde_json:: to_string ( & storage) . unwrap ( ) ;
154+
155+ // Deserialize the storage
156+ let deserialized: Box < dyn Storage > = serde_json:: from_str ( & serialized) . unwrap ( ) ;
157+
158+ // Verify the type is correct
159+ assert ! ( format!( "{:?}" , deserialized) . contains( "OpenDALFsStorage" ) ) ;
160+ }
161+ }
0 commit comments