1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! Filesystem abstraction.

use crate::{
    async_trait, //
    context::Context,
    io::{Reader, Writer},
    op::Operation,
};
use std::{future::Future, io, pin::Pin};

/// A set of callbacks for FUSE filesystem implementation.
#[async_trait]
pub trait Filesystem: Sync {
    /// Reply to a FUSE request.
    ///
    /// If there is no reply in the callback, the default reply (typically
    /// an `ENOSYS` error code) is automatically sent to the kernel.
    #[allow(unused_variables)]
    async fn call<'a, 'cx, T: ?Sized>(
        &'a self,
        cx: &'a mut Context<'cx, T>,
        op: Operation<'cx>,
    ) -> io::Result<()>
    where
        T: Reader + Writer + Send + Unpin,
    {
        Ok(())
    }
}

macro_rules! impl_filesystem_body {
    () => {
        #[inline]
        fn call<'a, 'cx, 'async_trait, T: ?Sized>(
            &'a self,
            cx: &'a mut Context<'cx, T>,
            op: Operation<'cx>,
        ) -> Pin<Box<dyn Future<Output = io::Result<()>> + Send + 'async_trait>>
        where
            'a: 'async_trait,
            'cx: 'async_trait,
            T: Reader + Writer + Send + Unpin + 'async_trait,
        {
            (**self).call(cx, op)
        }
    };
}

impl<F: ?Sized> Filesystem for &F
where
    F: Filesystem,
{
    impl_filesystem_body!();
}

impl<F: ?Sized> Filesystem for Box<F>
where
    F: Filesystem,
{
    impl_filesystem_body!();
}

impl<F: ?Sized> Filesystem for std::sync::Arc<F>
where
    F: Filesystem + Send,
{
    impl_filesystem_body!();
}