pub trait LayerExt: Fs + Sized {
// Provided method
fn layer<L: Layer<Self>>(self, layer: L) -> L::Backend { ... }
}Expand description
Extension trait for fluent layer composition.
Provides the .layer() method on any Fs backend for ergonomic chaining.
§Example
use anyfs_backend::{Fs, LayerExt, Layer};
// With LayerExt, you can chain layers fluently:
fn compose_backend<B: Fs, L: Layer<B>>(backend: B, layer: L) -> L::Backend {
backend.layer(layer)
}Provided Methods§
Sourcefn layer<L: Layer<Self>>(self, layer: L) -> L::Backend
fn layer<L: Layer<Self>>(self, layer: L) -> L::Backend
Apply a layer to this backend.
Returns the wrapped backend with the layer’s functionality added.
§Example
use anyfs_backend::{Fs, LayerExt, Layer};
fn add_middleware<B, L>(backend: B, layer: L) -> L::Backend
where
B: Fs,
L: Layer<B>,
{
backend.layer(layer)
}Examples found in repository?
examples/layer_middleware.rs (line 667)
648fn main() {
649 println!("=== Layer Middleware Example ===\n");
650
651 // Create base filesystem
652 let base = MemoryFs::new();
653
654 // Write some initial data
655 base.write(Path::new("/config.txt"), b"initial config")
656 .unwrap();
657 base.create_dir(Path::new("/data")).unwrap();
658 base.write(Path::new("/data/file1.txt"), b"file 1 content")
659 .unwrap();
660
661 // ===========================================
662 // Example 1: Logging layer
663 // ===========================================
664 println!("--- Example 1: Logging Layer ---\n");
665
666 // Using LayerExt for fluent API
667 let logged_fs = base.layer(LoggingLayer);
668
669 println!("Reading a file through logging layer:");
670 let _ = logged_fs.read(Path::new("/config.txt"));
671 println!();
672
673 // Get base back (we'll use a new one for other examples)
674 let base = MemoryFs::new();
675 base.write(Path::new("/config.txt"), b"initial config")
676 .unwrap();
677 base.create_dir(Path::new("/data")).unwrap();
678 base.write(Path::new("/data/file1.txt"), b"file 1 content")
679 .unwrap();
680 base.write(Path::new("/data/file2.txt"), b"file 2 content")
681 .unwrap();
682
683 // ===========================================
684 // Example 2: Metrics layer
685 // ===========================================
686 println!("--- Example 2: Metrics Layer ---\n");
687
688 let metrics_layer = MetricsLayer;
689 let metrics_fs = metrics_layer.layer(MemoryFs::new());
690
691 // Setup
692 metrics_fs.write(Path::new("/a.txt"), b"a").unwrap();
693 metrics_fs.write(Path::new("/b.txt"), b"b").unwrap();
694 metrics_fs.write(Path::new("/c.txt"), b"c").unwrap();
695 let _ = metrics_fs.read(Path::new("/a.txt"));
696 let _ = metrics_fs.read(Path::new("/b.txt"));
697 metrics_fs.remove_file(Path::new("/c.txt")).unwrap();
698
699 let (reads, writes, deletes) = metrics_fs.stats();
700 println!("Metrics: reads={reads}, writes={writes}, deletes={deletes}\n");
701
702 // ===========================================
703 // Example 3: Read-only layer
704 // ===========================================
705 println!("--- Example 3: Read-Only Layer ---\n");
706
707 let readonly_fs = base.layer(ReadOnlyLayer);
708
709 // Reading works
710 println!("Reading through read-only layer:");
711 match readonly_fs.read(Path::new("/config.txt")) {
712 Ok(data) => println!(" Success: {} bytes", data.len()),
713 Err(e) => println!(" Error: {e}"),
714 }
715
716 // Writing fails
717 println!("Writing through read-only layer:");
718 match readonly_fs.write(Path::new("/new.txt"), b"test") {
719 Ok(()) => println!(" Success (unexpected!)"),
720 Err(e) => println!(" Error: {e}"),
721 }
722 println!();
723
724 // ===========================================
725 // Example 4: Composing multiple layers
726 // ===========================================
727 println!("--- Example 4: Composing Layers ---\n");
728
729 // Create a stack: MemoryFs -> Metrics -> Logging
730 // Operations flow: Logging -> Metrics -> MemoryFs
731 let base = MemoryFs::new();
732 let with_metrics = MetricsLayer.layer(base);
733 let with_logging = LoggingLayer.layer(with_metrics);
734
735 println!("Writing through Logging -> Metrics -> Memory:");
736 with_logging
737 .write(Path::new("/test.txt"), b"hello")
738 .unwrap();
739 println!();
740
741 println!("Reading through Logging -> Metrics -> Memory:");
742 let _ = with_logging.read(Path::new("/test.txt"));
743 println!();
744
745 // Access inner metrics
746 let (reads, writes, _) = with_logging.inner.stats();
747 println!("Inner metrics: reads={reads}, writes={writes}\n");
748
749 // ===========================================
750 // Example 5: Using with trait objects
751 // ===========================================
752 println!("--- Example 5: Layers with Trait Objects ---\n");
753
754 fn use_any_fs(fs: &dyn Fs) {
755 let _ = fs.exists(Path::new("/"));
756 println!(" Used filesystem through trait object");
757 }
758
759 let base = MemoryFs::new();
760 let layered = base.layer(LoggingLayer);
761
762 println!("Passing layered FS as &dyn Fs:");
763 use_any_fs(&layered);
764
765 println!("\n=== Layer examples complete! ===");
766}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.