fn build()

in core/src/services/ftp/backend.rs [116:204]


    fn build(self) -> Result<impl Access> {
        debug!("ftp backend build started: {:?}", &self);
        let endpoint = match &self.config.endpoint {
            None => return Err(Error::new(ErrorKind::ConfigInvalid, "endpoint is empty")),
            Some(v) => v,
        };

        let endpoint_uri = match endpoint.parse::<Uri>() {
            Err(e) => {
                return Err(Error::new(ErrorKind::ConfigInvalid, "endpoint is invalid")
                    .with_context("endpoint", endpoint)
                    .set_source(e));
            }
            Ok(uri) => uri,
        };

        let host = endpoint_uri.host().unwrap_or("127.0.0.1");
        let port = endpoint_uri.port_u16().unwrap_or(21);

        let endpoint = format!("{host}:{port}");

        let enable_secure = match endpoint_uri.scheme_str() {
            Some("ftp") => false,
            // if the user forgot to add a scheme prefix
            // treat it as using secured scheme
            Some("ftps") | None => true,

            Some(s) => {
                return Err(Error::new(
                    ErrorKind::ConfigInvalid,
                    "endpoint is unsupported or invalid",
                )
                .with_context("endpoint", s));
            }
        };

        let root = normalize_root(&self.config.root.unwrap_or_default());

        let user = match &self.config.user {
            None => "".to_string(),
            Some(v) => v.clone(),
        };

        let password = match &self.config.password {
            None => "".to_string(),
            Some(v) => v.clone(),
        };

        let accessor_info = AccessorInfo::default();
        accessor_info
            .set_scheme(Scheme::Ftp)
            .set_root(&root)
            .set_native_capability(Capability {
                stat: true,
                stat_has_content_length: true,
                stat_has_last_modified: true,

                read: true,

                write: true,
                write_can_multi: true,
                write_can_append: true,

                delete: true,
                create_dir: true,

                list: true,
                list_has_content_length: true,
                list_has_last_modified: true,

                shared: true,

                ..Default::default()
            });
        let manager = Manager {
            endpoint: endpoint.clone(),
            root: root.clone(),
            user: user.clone(),
            password: password.clone(),
            enable_secure,
        };
        let core = Arc::new(FtpCore {
            info: accessor_info.into(),
            manager,
            pool: OnceCell::new(),
        });

        Ok(FtpBackend { core })
    }