LayerExt

Trait LayerExt 

Source
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§

Source

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.

Implementors§

Source§

impl<B: Fs> LayerExt for B