use crate::{FilesClient, PaginationInfo, Result};
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RemoteServerEntity {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub server_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub authentication_method: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hostname: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub port: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub username: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub remote_home_path: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ssl: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_connections: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pin_to_site_region: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pinned_region: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub s3_bucket: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub s3_region: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub aws_access_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub server_host_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub server_certificate: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub azure_blob_storage_account: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub azure_blob_storage_container: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub azure_blob_storage_dns_suffix: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub azure_blob_storage_hierarchical_namespace: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub azure_files_storage_account: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub azure_files_storage_share_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub azure_files_storage_dns_suffix: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub backblaze_b2_bucket: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub backblaze_b2_s3_endpoint: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub wasabi_bucket: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub wasabi_region: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub wasabi_access_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub google_cloud_storage_bucket: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub google_cloud_storage_project_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub s3_compatible_access_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub s3_compatible_bucket: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub s3_compatible_endpoint: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub s3_compatible_region: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub files_agent_api_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub files_agent_root: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub files_agent_permission_set: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub files_agent_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filebase_bucket: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filebase_access_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cloudflare_bucket: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cloudflare_access_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cloudflare_endpoint: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dropbox_teams: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub linode_bucket: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub linode_access_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub linode_region: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub one_drive_account_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disabled: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_versioning: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub enable_dedicated_ips: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_account_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_status: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub google_cloud_storage_s3_compatible_access_key: Option<String>,
}
pub struct RemoteServerHandler {
client: FilesClient,
}
impl RemoteServerHandler {
pub fn new(client: FilesClient) -> Self {
Self { client }
}
pub async fn list(
&self,
cursor: Option<&str>,
per_page: Option<i64>,
) -> Result<(Vec<RemoteServerEntity>, PaginationInfo)> {
let mut params = vec![];
if let Some(c) = cursor {
params.push(("cursor", c.to_string()));
}
if let Some(pp) = per_page {
params.push(("per_page", pp.to_string()));
}
let query = if params.is_empty() {
String::new()
} else {
format!(
"?{}",
params
.iter()
.map(|(k, v)| format!("{}={}", k, v))
.collect::<Vec<_>>()
.join("&")
)
};
let response = self
.client
.get_raw(&format!("/remote_servers{}", query))
.await?;
let servers: Vec<RemoteServerEntity> = serde_json::from_value(response)?;
let pagination = PaginationInfo {
cursor_next: None,
cursor_prev: None,
};
Ok((servers, pagination))
}
pub async fn get(&self, id: i64) -> Result<RemoteServerEntity> {
let response = self
.client
.get_raw(&format!("/remote_servers/{}", id))
.await?;
Ok(serde_json::from_value(response)?)
}
pub async fn get_configuration_file(&self, id: i64) -> Result<serde_json::Value> {
let response = self
.client
.get_raw(&format!("/remote_servers/{}/configuration_file", id))
.await?;
Ok(response)
}
#[allow(clippy::too_many_arguments)]
pub async fn create(
&self,
name: &str,
server_type: &str,
hostname: Option<&str>,
username: Option<&str>,
port: Option<i64>,
s3_bucket: Option<&str>,
s3_region: Option<&str>,
) -> Result<RemoteServerEntity> {
let mut request_body = json!({
"name": name,
"server_type": server_type,
});
if let Some(h) = hostname {
request_body["hostname"] = json!(h);
}
if let Some(u) = username {
request_body["username"] = json!(u);
}
if let Some(p) = port {
request_body["port"] = json!(p);
}
if let Some(b) = s3_bucket {
request_body["s3_bucket"] = json!(b);
}
if let Some(r) = s3_region {
request_body["s3_region"] = json!(r);
}
let response = self
.client
.post_raw("/remote_servers", request_body)
.await?;
Ok(serde_json::from_value(response)?)
}
#[allow(clippy::too_many_arguments)]
pub async fn update(
&self,
id: i64,
name: Option<&str>,
hostname: Option<&str>,
port: Option<i64>,
disabled: Option<bool>,
) -> Result<RemoteServerEntity> {
let mut request_body = json!({});
if let Some(n) = name {
request_body["name"] = json!(n);
}
if let Some(h) = hostname {
request_body["hostname"] = json!(h);
}
if let Some(p) = port {
request_body["port"] = json!(p);
}
if let Some(d) = disabled {
request_body["disabled"] = json!(d);
}
let response = self
.client
.patch_raw(&format!("/remote_servers/{}", id), request_body)
.await?;
Ok(serde_json::from_value(response)?)
}
pub async fn delete(&self, id: i64) -> Result<()> {
self.client
.delete_raw(&format!("/remote_servers/{}", id))
.await?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_handler_creation() {
let client = FilesClient::builder().api_key("test-key").build().unwrap();
let _handler = RemoteServerHandler::new(client);
}
}