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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//! Mock APIs for `std` traits

/// Mock APIs for `std::error` traits
#[cfg(feature = "mock-std")]
pub mod error {
    use crate::unimock;
    use std::error::Error;

    #[unimock(prefix=crate, api=ErrorMock, mirror=std::error::Error)]
    pub trait Error {
        fn source(&self) -> Option<&(dyn Error + 'static)> {}

        // deprecated:
        // fn description(&self) -> &str {}
        // fn cause(&self) -> Option<&dyn Error> {}

        // Note: Unstable
        // fn provide<'a>(&'a self, demand: &mut Demand<'a>) {}
    }
}

/// Mock APIs for `std::io` traits
#[cfg(feature = "mock-std")]
pub mod io {
    use std::io::{IoSlice, IoSliceMut, Result, SeekFrom};
    use std::{string::String, vec::Vec};

    use unimock_macros::unimock;

    #[unimock(prefix=crate, api=BufReadMock, mirror=std::io::BufRead)]
    pub trait BufRead: Read {
        fn fill_buf(&mut self) -> Result<&[u8]>;
        fn consume(&mut self, amt: usize);
        // unstable
        // fn has_data_left(&mut self) -> Result<bool> {}
        fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {}
        fn read_line(&mut self, buf: &mut String) -> Result<usize> {}
    }

    #[unimock(prefix=crate, api=ReadMock, mirror=std::io::Read)]
    pub trait Read {
        fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
        fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {}
        fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {}
        fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {}
        fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {}
    }

    #[unimock(prefix=crate, api=SeekMock, mirror=std::io::Seek)]
    pub trait Seek {
        fn seek(&mut self, pos: SeekFrom) -> Result<u64>;

        fn rewind(&mut self) -> Result<()> {}
        fn stream_position(&mut self) -> Result<u64> {}

        // unstable:
        // fn stream_len(&mut self) -> Result<u64> {}
    }

    #[unimock(prefix=crate, api=WriteMock, mirror=std::io::Write)]
    pub trait Write {
        fn write(&mut self, buf: &[u8]) -> Result<usize>;
        fn flush(&mut self) -> Result<()>;
        fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {}
        fn write_all(&mut self, buf: &[u8]) -> Result<()> {}

        // FIXME: This is not implemented (yet) because of self-lifetime in argument.
        // It just uses the default implementation which delegates to `Self::write`.
        // fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> std::io::Result<()> {}
    }
}

/// Mock APIs for `std::process` traits
#[cfg(feature = "mock-std")]
pub mod process {
    /// Unimock mock API for [std::process::Termination].
    #[allow(non_snake_case)]
    pub mod TerminationMock {
        use crate::{output::Owning, MockFn};
        use std::{boxed::Box, string::String};

        #[allow(non_camel_case_types)]
        /// MockFn for [`Termination::report() -> ExitCode`](std::process::Termination::report).
        ///
        /// Note: This mock is partial by default.
        /// i.e. unless explicitly mocked, it reports Unimock's real errors and status for use in tests.
        pub struct report;

        impl MockFn for report {
            type Inputs<'i> = ();
            type OutputKind = Owning<std::process::ExitCode>;
            type AnswerFn = dyn Fn() -> Self + Send + Sync;

            fn info() -> crate::MockFnInfo {
                let mut info = crate::MockFnInfo::new::<Self>().path(&["Termination", "report"]);
                info.partial_by_default = true;
                info
            }

            fn debug_inputs(_: &Self::Inputs<'_>) -> Box<[Option<String>]> {
                Box::new([])
            }
        }
    }
}