Skip to main content

mockforge_ftp/
protocol_server.rs

1//! Unified protocol server implementation for the FTP mock server.
2
3use async_trait::async_trait;
4use mockforge_core::config::FtpConfig;
5use mockforge_core::protocol_abstraction::Protocol;
6use mockforge_core::protocol_server::MockProtocolServer;
7
8use crate::server::FtpServer;
9
10/// A `MockProtocolServer` wrapper around [`FtpServer`].
11///
12/// Constructs the FTP server (including VFS and spec registry), then
13/// delegates to [`FtpServer::start`] with shutdown-signal integration.
14pub struct FtpMockServer {
15    config: FtpConfig,
16}
17
18impl FtpMockServer {
19    /// Create a new `FtpMockServer` with the given configuration.
20    pub fn new(config: FtpConfig) -> Self {
21        Self { config }
22    }
23}
24
25#[async_trait]
26impl MockProtocolServer for FtpMockServer {
27    fn protocol(&self) -> Protocol {
28        Protocol::Ftp
29    }
30
31    async fn start(
32        &self,
33        mut shutdown: tokio::sync::watch::Receiver<()>,
34    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
35        let server = FtpServer::new(self.config.clone());
36
37        tokio::select! {
38            result = server.start() => {
39                result.map_err(|e| -> Box<dyn std::error::Error + Send + Sync> {
40                    Box::new(std::io::Error::other(e.to_string()))
41                })
42            }
43            _ = shutdown.changed() => {
44                tracing::info!("Shutting down FTP server on port {}", self.config.port);
45                Ok(())
46            }
47        }
48    }
49
50    fn port(&self) -> u16 {
51        self.config.port
52    }
53
54    fn description(&self) -> String {
55        format!("FTP server on {}:{}", self.config.host, self.config.port)
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[test]
64    fn test_ftp_mock_server_protocol() {
65        let server = FtpMockServer::new(FtpConfig::default());
66        assert_eq!(server.protocol(), Protocol::Ftp);
67    }
68
69    #[test]
70    fn test_ftp_mock_server_port() {
71        let server = FtpMockServer::new(FtpConfig::default());
72        assert_eq!(server.port(), server.config.port);
73    }
74
75    #[test]
76    fn test_ftp_mock_server_description() {
77        let config = FtpConfig {
78            host: "127.0.0.1".to_string(),
79            port: 2121,
80            ..Default::default()
81        };
82        let server = FtpMockServer::new(config);
83        assert_eq!(server.description(), "FTP server on 127.0.0.1:2121");
84    }
85}