diff --git a/rfs-client/.gitignore b/rfs-client/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/rfs-client/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/rfs-client/Cargo.toml b/rfs-client/Cargo.toml new file mode 100644 index 0000000..8432d93 --- /dev/null +++ b/rfs-client/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "rfs-client" +version = "0.1.0" +edition = "2021" +description = "Client library for RFS (Remote File System) server" +license = "MIT" + +[dependencies] +openapi = { path = "./openapi" } +thiserror = "1.0" +url = "2.4" +reqwest = { version = "^0.12", features = ["json", "multipart"] } +tokio = { version = "1.28", features = ["full"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +log = "0.4" +bytes = "1.4" +futures = "0.3" diff --git a/rfs-client/README.md b/rfs-client/README.md new file mode 100644 index 0000000..1392a62 --- /dev/null +++ b/rfs-client/README.md @@ -0,0 +1,195 @@ +# RFS Client + +A Rust client library for interacting with the Remote File System (RFS) server. + +## Overview + +This client library provides a user-friendly wrapper around the OpenAPI-generated client code. It offers high-level abstractions for common operations such as: + +- Authentication and session management +- File uploads and downloads with progress tracking +- Block-level operations and verification +- FList creation, monitoring, and management +- Timeout configuration and error handling + +## Structure + +The library is organized as follows: + +- `client.rs`: Main client implementation with methods for interacting with the RFS server +- `error.rs`: Error types and handling +- `types.rs`: Type definitions and utilities + +## Quick Start + +```rust +use rfs_client::RfsClient; +use rfs_client::types::{ClientConfig, Credentials}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client with custom configuration + let config = ClientConfig { + base_url: "http://localhost:8080".to_string(), + credentials: Some(Credentials { + username: "user".to_string(), + password: "password".to_string(), + }), + timeout_seconds: 60, + }; + + let mut client = RfsClient::new(config); + + // Authenticate + client.authenticate().await?; + println!("Authentication successful"); + + // Upload a file + let file_path = "/path/to/file.txt"; + let file_hash = client.upload_file(file_path, None).await?; + println!("File uploaded with hash: {}", file_hash); + + // Download the file + let output_path = "/path/to/output.txt"; + client.download_file(&file_hash, output_path, None).await?; + println!("File downloaded to {}", output_path); + + Ok(()) +} +``` + +## Feature Examples + +### Authentication + +```rust +// Create a client with authentication +let config = ClientConfig { + base_url: "http://localhost:8080".to_string(), + credentials: Some(Credentials { + username: "user".to_string(), + password: "password".to_string(), + }), + timeout_seconds: 30, +}; + +let mut client = RfsClient::new(config); + +// Authenticate with the server +client.authenticate().await?; +if client.is_authenticated() { + println!("Authentication successful"); +} +``` + +### File Management + +```rust +// Upload a file with options +let upload_options = UploadOptions { + chunk_size: Some(1024 * 1024), // 1MB chunks + verify: true, +}; + +let file_hash = client.upload_file("/path/to/file.txt", Some(upload_options)).await?; + +// Download the file +let download_options = DownloadOptions { + verify: true, +}; + +client.download_file(&file_hash, "/path/to/output.txt", Some(download_options)).await?; +``` + +### FList Operations + +```rust +// Create an FList from a Docker image +let options = FlistOptions { + auth: None, + username: None, + password: None, + email: None, + server_address: Some("docker.io".to_string()), + identity_token: None, + registry_token: None, +}; + +let job_id = client.create_flist("alpine:latest", Some(options)).await?; + +// Wait for FList creation with progress tracking +let wait_options = WaitOptions { + timeout_seconds: 60, + poll_interval_ms: 1000, + progress_callback: Some(Box::new(|state| { + println!("Progress: FList state is now {:?}", state); + })), +}; + +let final_state = client.wait_for_flist_creation(&job_id, Some(wait_options)).await?; + +// List available FLists +let flists = client.list_flists().await?; + +// Preview an FList +let preview = client.preview_flist("flists/user/alpine-latest.fl").await?; + +// Download an FList +client.download_flist("flists/user/alpine-latest.fl", "/tmp/downloaded_flist.fl").await?; +``` + +### Block Management + +```rust +// List blocks +let blocks_list = client.list_blocks(None).await?; + +// Check if a block exists +let exists = client.check_block("block_hash").await?; + +// Get block content +let block_content = client.get_block("block_hash").await?; + +// Upload a block +let block_hash = client.upload_block("file_hash", 0, data).await?; + +// Verify blocks +let request = VerifyBlocksRequest { blocks: verify_blocks }; +let verify_result = client.verify_blocks(request).await?; +``` + +## Complete Examples + +For more detailed examples, check the `examples` directory: + +- `authentication.rs`: Authentication and health check examples +- `file_management.rs`: File upload and download with verification +- `flist_operations.rs`: Complete FList creation, monitoring, listing, preview, and download +- `block_management.rs`: Block-level operations including listing, verification, and upload +- `wait_for_flist.rs`: Advanced FList creation with progress monitoring + +Run an example with: + +```bash +cargo run --example flist_operations +``` + +## Development + +This library wraps the OpenAPI-generated client located in the `openapi` directory. The OpenAPI client was generated using the OpenAPI Generator CLI. + +To build the library: + +```bash +cargo build +``` + +To run tests: + +```bash +cargo test +``` + +## License + +MIT diff --git a/rfs-client/examples/authentication.rs b/rfs-client/examples/authentication.rs new file mode 100644 index 0000000..0f19001 --- /dev/null +++ b/rfs-client/examples/authentication.rs @@ -0,0 +1,42 @@ +use rfs_client::RfsClient; +use rfs_client::types::{ClientConfig, Credentials}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client with authentication credentials + let config = ClientConfig { + base_url: "http://localhost:8080".to_string(), + credentials: Some(Credentials { + username: "user".to_string(), + password: "password".to_string(), + }), + timeout_seconds: 30, + }; + + let mut client = RfsClient::new(config); + println!("Client created with authentication credentials"); + + // Authenticate with the server + client.authenticate().await?; + if client.is_authenticated() { + println!("Authentication successful"); + } else { + println!("Authentication failed"); + } + + // Create a client without authentication + let config_no_auth = ClientConfig { + base_url: "http://localhost:8080".to_string(), + credentials: None, + timeout_seconds: 30, + }; + + let client_no_auth = RfsClient::new(config_no_auth); + println!("Client created without authentication credentials"); + + // Check health endpoint (doesn't require authentication) + let health = client_no_auth.health_check().await?; + println!("Server health: {:?}", health); + + Ok(()) +} diff --git a/rfs-client/examples/block_management.rs b/rfs-client/examples/block_management.rs new file mode 100644 index 0000000..b029d7a --- /dev/null +++ b/rfs-client/examples/block_management.rs @@ -0,0 +1,128 @@ +use rfs_client::RfsClient; +use rfs_client::types::{ClientConfig, Credentials}; +use openapi::models::{VerifyBlock, VerifyBlocksRequest}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client with authentication + let config = ClientConfig { + base_url: "http://localhost:8080".to_string(), + credentials: Some(Credentials { + username: "user".to_string(), + password: "password".to_string(), + }), + timeout_seconds: 60, + }; + + let mut client = RfsClient::new(config); + + // Authenticate with the server + client.authenticate().await?; + println!("Authentication successful"); + + // Create a test file to upload for block testing + let test_file_path = "/tmp/block_test.txt"; + let test_content = "This is a test file for RFS client block management"; + std::fs::write(test_file_path, test_content)?; + println!("Created test file at {}", test_file_path); + + // Upload the file to get blocks + println!("Uploading file to get blocks..."); + let file_hash = client.upload_file(test_file_path, None).await?; + println!("File uploaded with hash: {}", file_hash); + + // Get blocks by file hash + println!("Getting blocks for file hash: {}", file_hash); + let blocks = client.get_blocks_by_hash(&file_hash).await?; + println!("Found {} blocks for the file", blocks.blocks.len()); + + // Print block information + for (i, block_data) in blocks.blocks.iter().enumerate() { + println!("Block {}: Hash={}, Index={}", i, block_data.hash, block_data.index); + } + + // Verify blocks with complete information + println!("Verifying blocks..."); + + // Create a list of VerifyBlock objects with complete information + let verify_blocks = blocks.blocks.iter().map(|block| { + VerifyBlock { + block_hash: block.hash.clone(), + block_index: block.index, + file_hash: file_hash.clone(), // Using the actual file hash + } + }).collect::>(); + + // Create the request with the complete block information + for block in verify_blocks.iter() { + println!("Block: {}", block.block_hash); + println!("Block index: {}", block.block_index); + println!("File hash: {}", block.file_hash); + } + let request = VerifyBlocksRequest { blocks: verify_blocks }; + + // Send the verification request + let verify_result = client.verify_blocks(request).await?; + println!("Verification result: {} missing blocks", verify_result.missing.len()); + for block in verify_result.missing.iter() { + println!("Missing block: {}", block); + } + + // List blocks (list_blocks_handler) + println!("\n1. Listing all blocks with pagination..."); + let blocks_list = client.list_blocks(None).await?; + println!("Server has {} blocks in total", blocks_list.len()); + if !blocks_list.is_empty() { + let first_few = blocks_list.iter().take(3) + .map(|s| s.as_str()) + .collect::>() + .join(", "); + println!("First few blocks: {}", first_few); + } + + // Check if a block exists (check_block_handler) + if !blocks.blocks.is_empty() { + let block_to_check = &blocks.blocks[0].hash; + println!("\n2. Checking if block exists: {}", block_to_check); + let exists = client.check_block(block_to_check).await?; + println!("Block exists: {}", exists); + } + + // Get block downloads statistics (get_block_downloads_handler) + if !blocks.blocks.is_empty() { + let block_to_check = &blocks.blocks[0].hash; + println!("\n3. Getting download statistics for block: {}", block_to_check); + let downloads = client.get_block_downloads(block_to_check).await?; + println!("Block has been downloaded {} times", downloads.downloads_count); + } + + // Get a specific block content (get_block_handler) + if !blocks.blocks.is_empty() { + let block_to_get = &blocks.blocks[0].hash; + println!("\n4. Getting content for block: {}", block_to_get); + let block_content = client.get_block(block_to_get).await?; + println!("Retrieved block with {} bytes", block_content.len()); + } + + // Get user blocks (get_user_blocks_handler) + println!("\n6. Listing user blocks..."); + let user_blocks = client.get_user_blocks(Some(1), Some(10)).await?; + println!("User has {} blocks (showing page 1 with 10 per page)", user_blocks.total); + for block in user_blocks.blocks.iter().take(3) { + println!(" - Block: {}, Index: {}", block.hash, block.index); + } + + // Upload a block (upload_block_handler) + println!("\n7. Uploading a new test block..."); + let test_block_data = b"This is test block data for direct block upload"; + let new_file_hash = "test_file_hash_for_block_upload"; + let block_index = 0; + let block_hash = client.upload_block(new_file_hash, block_index, test_block_data.to_vec()).await?; + println!("Uploaded block with hash: {}", block_hash); + + // Clean up + std::fs::remove_file(test_file_path)?; + println!("Test file cleaned up"); + + Ok(()) +} diff --git a/rfs-client/examples/file_management.rs b/rfs-client/examples/file_management.rs new file mode 100644 index 0000000..40794ed --- /dev/null +++ b/rfs-client/examples/file_management.rs @@ -0,0 +1,64 @@ +use rfs_client::RfsClient; +use rfs_client::types::{ClientConfig, Credentials, UploadOptions, DownloadOptions}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client with authentication + let config = ClientConfig { + base_url: "http://localhost:8080".to_string(), + credentials: Some(Credentials { + username: "user".to_string(), + password: "password".to_string(), + }), + timeout_seconds: 60, + }; + + let mut client = RfsClient::new(config); + + // Authenticate with the server + client.authenticate().await?; + println!("Authentication successful"); + + // Create a test file to upload + let test_file_path = "/tmp/test_upload.txt"; + std::fs::write(test_file_path, "This is a test file for RFS client upload")?; + println!("Created test file at {}", test_file_path); + + // Upload the file with options + println!("Uploading file..."); + let upload_options = UploadOptions { + chunk_size: Some(1024 * 1024), // 1MB chunks + verify: true, + }; + + let file_hash = client.upload_file(test_file_path, Some(upload_options)).await?; + println!("File uploaded with hash: {}", file_hash); + + // Download the file + let download_path = "/tmp/test_download.txt"; + println!("Downloading file to {}...", download_path); + + let download_options = DownloadOptions { + verify: true, + }; + + client.download_file(&file_hash, download_path, Some(download_options)).await?; + println!("File downloaded to {}", download_path); + + // Verify the downloaded file matches the original + let original_content = std::fs::read_to_string(test_file_path)?; + let downloaded_content = std::fs::read_to_string(download_path)?; + + if original_content == downloaded_content { + println!("File contents match! Download successful."); + } else { + println!("ERROR: File contents do not match!"); + } + + // Clean up test files + std::fs::remove_file(test_file_path)?; + std::fs::remove_file(download_path)?; + println!("Test files cleaned up"); + + Ok(()) +} diff --git a/rfs-client/examples/flist_operations.rs b/rfs-client/examples/flist_operations.rs new file mode 100644 index 0000000..ad57cc5 --- /dev/null +++ b/rfs-client/examples/flist_operations.rs @@ -0,0 +1,171 @@ +use rfs_client::RfsClient; +use rfs_client::types::{ClientConfig, Credentials, FlistOptions, WaitOptions}; +use std::path::Path; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let parent_dir = "flists"; + // Create a client with authentication + let config = ClientConfig { + base_url: "http://localhost:8080".to_string(), + credentials: Some(Credentials { + username: "user".to_string(), + password: "password".to_string(), + }), + timeout_seconds: 60, + }; + + let mut client = RfsClient::new(config); + + // Authenticate with the server + client.authenticate().await?; + println!("Authentication successful"); + + println!("\n1. CREATE FLIST - Creating an FList from a Docker image"); + let image_name = "alpine:latest"; + println!("Creating FList for image: {}", image_name); + + // Use FlistOptions to specify additional parameters + let options = FlistOptions { + auth: None, + username: None, + password: None, + email: None, + server_address: Some("docker.io".to_string()), + identity_token: None, + registry_token: None, + }; + + // Create the FList and handle potential conflict error + let job_id = match client.create_flist(&image_name, Some(options)).await { + Ok(id) => { + println!("FList creation started with job ID: {}", id); + Some(id) + }, + Err(e) => { + if e.to_string().contains("Conflict") { + println!("FList already exists"); + None + } else { + return Err(e.into()); + } + } + }; + + // 2. Check FList state if we have a job ID + if let Some(job_id) = &job_id { + println!("\n2. GET FLIST STATE - Checking FList creation state"); + let state = client.get_flist_state(job_id).await?; + println!("Current FList state: {:?}", state.flist_state); + + // 3. Wait for FList creation with progress reporting + println!("\n3. WAIT FOR FLIST CREATION - Waiting for FList to be created with progress reporting"); + let wait_options = WaitOptions { + timeout_seconds: 60, // Shorter timeout for the example + poll_interval_ms: 1000, + progress_callback: Some(Box::new(|state| { + println!("Progress: FList state is now {:?}", state); + // No return value needed (returns unit type) + })), + }; + + // Wait for the FList to be created (with a timeout) + match client.wait_for_flist_creation(job_id, Some(wait_options)).await { + Ok(final_state) => { + println!("FList creation completed with state: {:?}", final_state); + }, + Err(e) => { + println!("Error waiting for FList creation: {}", e); + // Continue with the example even if waiting fails + } + }; + } + + // 4. List all available FLists + println!("\n4. LIST FLISTS - Listing all available FLists"); + + // Variable to store the FList path for preview and download + let mut flist_path_for_preview: Option = None; + + match client.list_flists().await { + Ok(flists) => { + println!("Found {} FList categories", flists.len()); + + for (category, files) in &flists { + println!("Category: {}", category); + for file in files.iter().take(2) { // Show only first 2 files per category + println!(" - {} (size: {} bytes)", file.name, file.size); + + // Save the first FList path for preview + if flist_path_for_preview.is_none() { + let path = format!("{}/{}/{}", parent_dir, category, file.name); + flist_path_for_preview = Some(path); + } + } + if files.len() > 2 { + println!(" - ... and {} more files", files.len() - 2); + } + } + + // 5. Preview an FList if we found one + if let Some(ref flist_path) = flist_path_for_preview { + println!("\n5. PREVIEW FLIST - Previewing FList: {}", flist_path); + match client.preview_flist(flist_path).await { + Ok(preview) => { + println!("FList preview for {}:", flist_path); + println!(" - Checksum: {}", preview.checksum); + println!(" - Metadata: {}", preview.metadata); + + // Display content (list of strings) + if !preview.content.is_empty() { + println!(" - Content entries:"); + for (i, entry) in preview.content.iter().enumerate().take(5) { + println!(" {}. {}", i+1, entry); + } + if preview.content.len() > 5 { + println!(" ... and {} more entries", preview.content.len() - 5); + } + } + }, + Err(e) => println!("Error previewing FList: {}", e), + } + } else { + println!("No FLists available for preview"); + } + }, + Err(e) => println!("Error listing FLists: {}", e), + } + + // 6. DOWNLOAD FLIST - Downloading an FList to a local file + if let Some(ref flist_path) = flist_path_for_preview { + println!("\n6. DOWNLOAD FLIST - Downloading FList: {}", flist_path); + + // Create a temporary output path for the downloaded FList + let output_path = "/tmp/downloaded_flist.fl"; + + match client.download_flist(flist_path, output_path).await { + Ok(_) => { + println!("FList successfully downloaded to {}", output_path); + + // Get file size + match std::fs::metadata(output_path) { + Ok(metadata) => println!("Downloaded file size: {} bytes", metadata.len()), + Err(e) => println!("Error getting file metadata: {}", e), + } + }, + Err(e) => println!("Error downloading FList: {}", e), + } + } else { + println!("\n6. DOWNLOAD FLIST - No FList available for download"); + } + + println!("\nAll FList operations demonstrated:"); + println!("1. create_flist - Create a new FList from a Docker image"); + println!("2. get_flist_state - Check the state of an FList creation job"); + println!("3. wait_for_flist_creation - Wait for an FList to be created with progress reporting"); + println!("4. list_flists - List all available FLists"); + println!("5. preview_flist - Preview the content of an FList"); + println!("6. download_flist - Download an FList to a local file"); + + Ok(()) +} diff --git a/rfs-client/examples/wait_for_flist.rs b/rfs-client/examples/wait_for_flist.rs new file mode 100644 index 0000000..e5ef4f0 --- /dev/null +++ b/rfs-client/examples/wait_for_flist.rs @@ -0,0 +1,61 @@ +use rfs_client::RfsClient; +use rfs_client::types::{ClientConfig, Credentials, WaitOptions}; +use openapi::models::FlistState; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a client with authentication + let config = ClientConfig { + base_url: "http://localhost:8080".to_string(), + credentials: Some(Credentials { + username: "user".to_string(), + password: "password".to_string(), + }), + timeout_seconds: 60, + }; + + let mut client = RfsClient::new(config); + + // Authenticate with the server + client.authenticate().await?; + println!("Authentication successful"); + + // Create an FList from a Docker image + let image_name = "redis:latest"; + println!("Creating FList for image: {}", image_name); + + let job_id = client.create_flist(&image_name, None).await?; + println!("FList creation started with job ID: {}", job_id); + + // Set up options for waiting with progress reporting + let options = WaitOptions { + timeout_seconds: 600, // 10 minutes timeout + poll_interval_ms: 2000, // Check every 2 seconds + progress_callback: Some(Box::new(|state| { + match state { + FlistState::FlistStateInProgress(info) => { + println!("Progress: {:.1}% - {}", info.in_progress.progress, info.in_progress.msg); + }, + FlistState::FlistStateStarted(_) => { + println!("FList creation started..."); + }, + FlistState::FlistStateAccepted(_) => { + println!("FList creation request accepted..."); + }, + _ => println!("State: {:?}", state), + } + })), + }; + + // Wait for the FList to be created + println!("Waiting for FList creation to complete..."); + + // Use ? operator to propagate errors properly + let state = client.wait_for_flist_creation(&job_id, Some(options)).await + .map_err(|e| -> Box { Box::new(e) })?; + + println!("FList created successfully!"); + println!("Final state: {:?}", state); + + Ok(()) +} diff --git a/rfs-client/openapi.json b/rfs-client/openapi.json new file mode 100644 index 0000000..76b076b --- /dev/null +++ b/rfs-client/openapi.json @@ -0,0 +1 @@ +{"openapi":"3.0.3","info":{"title":"rfs","description":"","license":{"name":""},"version":"0.2.0"},"paths":{"/api/v1":{"get":{"tags":["System"],"operationId":"health_check_handler","responses":{"200":{"description":"flist server is working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/api/v1/block":{"post":{"tags":["Block Management"],"summary":"Upload a block to the server.","description":"If the block already exists, the server will return a 200 OK response.\nIf the block is new, the server will return a 201 Created response.","operationId":"upload_block_handler","parameters":[{"name":"file_hash","in":"query","description":"File hash associated with the block","required":true,"schema":{"type":"string"}},{"name":"idx","in":"query","description":"Block index within the file","required":true,"schema":{"type":"integer","format":"int64","minimum":0}}],"requestBody":{"description":"Block data to upload","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}},"required":true},"responses":{"200":{"description":"Block already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockUploadedResponse"}}}},"201":{"description":"Block created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockUploadedResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/block/verify":{"post":{"tags":["Block Management"],"summary":"Verify if multiple blocks exist on the server.","description":"Returns a list of missing blocks.","operationId":"verify_blocks_handler","requestBody":{"description":"List of block hashes to verify","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyBlocksRequest"}}},"required":true},"responses":{"200":{"description":"Verification completed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyBlocksResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}}}},"/api/v1/block/{hash}":{"get":{"tags":["Block Management"],"summary":"Retrieve a block by its hash.","operationId":"get_block_handler","parameters":[{"name":"hash","in":"path","description":"Block hash","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Block found","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Block not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}}},"head":{"tags":["Block Management"],"summary":"Checks a block by its hash.","operationId":"check_block_handler","parameters":[{"name":"hash","in":"path","description":"Block hash","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Block found"},"404":{"description":"Block not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}}}},"/api/v1/block/{hash}/downloads":{"get":{"tags":["Block Management"],"summary":"Retrieve the number of times a block has been downloaded.","operationId":"get_block_downloads_handler","parameters":[{"name":"hash","in":"path","description":"Block hash","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Download count retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockDownloadsResponse"}}}},"404":{"description":"Block not found"},"500":{"description":"Internal server error"}}}},"/api/v1/blocks":{"get":{"tags":["Block Management"],"summary":"List all block hashes in the server with pagination","operationId":"list_blocks_handler","parameters":[{"name":"page","in":"query","description":"Page number (1-indexed)","required":false,"schema":{"type":"integer","format":"int32","nullable":true,"minimum":0}},{"name":"per_page","in":"query","description":"Number of items per page","required":false,"schema":{"type":"integer","format":"int32","nullable":true,"minimum":0}}],"responses":{"200":{"description":"List of block hashes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListBlocksResponse"}}}},"400":{"description":"Bad request"},"500":{"description":"Internal server error"}}}},"/api/v1/blocks/{hash}":{"get":{"tags":["Block Management"],"summary":"Retrieve blocks by hash (file hash or block hash).","description":"If the hash is a file hash, returns all blocks with their block index related to that file.\nIf the hash is a block hash, returns the block itself.","operationId":"get_blocks_by_hash_handler","parameters":[{"name":"hash","in":"path","description":"File hash or block hash","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Blocks found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlocksResponse"}}}},"404":{"description":"Hash not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}}}},"/api/v1/file":{"post":{"tags":["File Management"],"summary":"Upload a file to the server.","description":"The file will be split into blocks and stored in the database.","operationId":"upload_file_handler","requestBody":{"description":"File data to upload","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}},"required":true},"responses":{"201":{"description":"File uploaded successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/file/{hash}":{"get":{"tags":["File Management"],"summary":"Retrieve a file by its hash from path, with optional custom filename in request body.","description":"The file will be reconstructed from its blocks.","operationId":"get_file_handler","parameters":[{"name":"hash","in":"path","description":"File hash","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Optional custom filename for download","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileDownloadRequest"}}},"required":true},"responses":{"200":{"description":"File found","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"File not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}}}},"/api/v1/fl":{"get":{"tags":["Flist Management"],"operationId":"list_flists_handler","responses":{"200":{"description":"Listing flists","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/FileInfo"}}}}}},"401":{"description":"Unauthorized user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}}},"post":{"tags":["Flist Management"],"operationId":"create_flist_handler","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlistBody"}}},"required":true},"responses":{"201":{"description":"Flist conversion started","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"401":{"description":"Unauthorized user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/fl/preview/{flist_path}":{"get":{"tags":["Flist Management"],"operationId":"preview_flist_handler","parameters":[{"name":"flist_path","in":"path","description":"flist file path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Flist preview result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"401":{"description":"Unauthorized user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}}}},"/api/v1/fl/{job_id}":{"get":{"tags":["Flist Management"],"operationId":"get_flist_state_handler","parameters":[{"name":"job_id","in":"path","description":"flist job id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Flist state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlistStateResponse"}}}},"401":{"description":"Unauthorized user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"404":{"description":"Flist not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/signin":{"post":{"tags":["Authentication"],"operationId":"sign_in_handler","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignInBody"}}},"required":true},"responses":{"201":{"description":"User signed in successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignInResponse"}}}},"401":{"description":"Unauthorized user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}}}},"/api/v1/user/blocks":{"get":{"tags":["Block Management"],"summary":"Retrieve all blocks uploaded by a specific user.","operationId":"get_user_blocks_handler","parameters":[{"name":"page","in":"query","description":"Page number (1-indexed)","required":false,"schema":{"type":"integer","format":"int32","nullable":true,"minimum":0}},{"name":"per_page","in":"query","description":"Number of items per page","required":false,"schema":{"type":"integer","format":"int32","nullable":true,"minimum":0}}],"responses":{"200":{"description":"Blocks found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserBlocksResponse"}}}},"401":{"description":"Unauthorized"},"500":{"description":"Internal server error"}},"security":[{"bearerAuth":[]}]}},"/api/v1/website/{website_hash}/{path}":{"get":{"tags":["Website Serving"],"operationId":"serve_website_handler","parameters":[{"name":"website_hash","in":"path","description":"flist hash of the website directory","required":true,"schema":{"type":"string"}},{"name":"path","in":"path","description":"Path to the file within the website directory, defaults to index.html if empty","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Website file served successfully","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"File not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}}}},"/{path}":{"get":{"tags":["Flist Management"],"summary":"Serve flist files from the server's filesystem","operationId":"serve_flists","parameters":[{"name":"path","in":"path","description":"Path to the flist file or directory to serve","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully served the flist or directory listing","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Flist not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponseError"}}}}}}}},"components":{"schemas":{"BlockDownloadsResponse":{"type":"object","description":"Response for block downloads endpoint","required":["block_hash","downloads_count","block_size"],"properties":{"block_hash":{"type":"string","description":"Block hash"},"block_size":{"type":"integer","format":"int64","description":"Size of the block in bytes","minimum":0},"downloads_count":{"type":"integer","format":"int64","description":"Number of times the block has been downloaded","minimum":0}}},"BlockInfo":{"type":"object","description":"Block information with hash and index","required":["hash","index"],"properties":{"hash":{"type":"string","description":"Block hash"},"index":{"type":"integer","format":"int64","description":"Block index within the file","minimum":0}}},"BlockUploadedResponse":{"type":"object","required":["hash","message"],"properties":{"hash":{"type":"string"},"message":{"type":"string"}}},"BlocksResponse":{"type":"object","description":"Response for blocks by hash endpoint","required":["blocks"],"properties":{"blocks":{"type":"array","items":{"$ref":"#/components/schemas/BlockInfo"},"description":"List of blocks with their indices"}}},"DirListTemplate":{"type":"object","required":["lister","cur_path"],"properties":{"cur_path":{"type":"string"},"lister":{"$ref":"#/components/schemas/DirLister"}}},"DirLister":{"type":"object","required":["files"],"properties":{"files":{"type":"array","items":{"$ref":"#/components/schemas/FileInfo"}}}},"ErrorTemplate":{"type":"object","required":["err","cur_path","message"],"properties":{"cur_path":{"type":"string"},"err":{"$ref":"#/components/schemas/TemplateErr"},"message":{"type":"string"}}},"FileDownloadRequest":{"type":"object","description":"Request for file download with custom filename","required":["file_name"],"properties":{"file_name":{"type":"string","description":"The custom filename to use for download"}}},"FileInfo":{"type":"object","required":["name","path_uri","is_file","size","last_modified","progress"],"properties":{"is_file":{"type":"boolean"},"last_modified":{"type":"integer","format":"int64"},"name":{"type":"string"},"path_uri":{"type":"string"},"progress":{"type":"number","format":"float"},"size":{"type":"integer","format":"int64","minimum":0}}},"FileUploadResponse":{"type":"object","description":"Response for file upload","required":["file_hash","message"],"properties":{"file_hash":{"type":"string","description":"The file hash"},"message":{"type":"string","description":"Message indicating success"}}},"FlistBody":{"type":"object","required":["image_name"],"properties":{"auth":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"identity_token":{"type":"string","nullable":true},"image_name":{"type":"string","example":"redis"},"password":{"type":"string","nullable":true},"registry_token":{"type":"string","nullable":true},"server_address":{"type":"string","nullable":true},"username":{"type":"string","nullable":true}}},"FlistState":{"oneOf":[{"type":"object","title":"FlistStateAccepted","required":["Accepted"],"properties":{"Accepted":{"type":"string"}}},{"type":"object","title":"FlistStateStarted","required":["Started"],"properties":{"Started":{"type":"string"}}},{"type":"object","title":"FlistStateInProgress","required":["InProgress"],"properties":{"InProgress":{"$ref":"#/components/schemas/FlistStateInfo"}}},{"type":"object","title":"FlistStateCreated","required":["Created"],"properties":{"Created":{"type":"string"}}},{"type":"string","title":"FlistStateFailed","enum":["Failed"]}]},"FlistStateInfo":{"type":"object","required":["msg","progress"],"properties":{"msg":{"type":"string"},"progress":{"type":"number","format":"float"}}},"FlistStateResponse":{"type":"object","required":["flist_state"],"properties":{"flist_state":{"$ref":"#/components/schemas/FlistState"}}},"HealthResponse":{"type":"object","required":["msg"],"properties":{"msg":{"type":"string"}}},"Job":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}},"ListBlocksParams":{"type":"object","description":"Query parameters for listing blocks","properties":{"page":{"type":"integer","format":"int32","description":"Page number (1-indexed)","default":1,"nullable":true,"minimum":1},"per_page":{"type":"integer","format":"int32","description":"Number of items per page","default":50,"nullable":true,"maximum":100,"minimum":1}}},"ListBlocksResponse":{"type":"object","description":"Response for listing blocks","required":["blocks","total","page","per_page"],"properties":{"blocks":{"type":"array","items":{"type":"string"},"description":"List of block hashes"},"page":{"type":"integer","format":"int32","description":"Current page number","minimum":0},"per_page":{"type":"integer","format":"int32","description":"Number of items per page","minimum":0},"total":{"type":"integer","format":"int64","description":"Total number of blocks","minimum":0}}},"PreviewResponse":{"type":"object","required":["content","metadata","checksum"],"properties":{"checksum":{"type":"string"},"content":{"type":"array","items":{"type":"string"}},"metadata":{"type":"string"}}},"ResponseError":{"oneOf":[{"type":"string","title":"ResponseErrorInternalServerError","enum":["InternalServerError"]},{"type":"object","title":"ResponseErrorConflict","required":["Conflict"],"properties":{"Conflict":{"type":"string"}}},{"type":"object","title":"ResponseErrorNotFound","required":["NotFound"],"properties":{"NotFound":{"type":"string"}}},{"type":"object","title":"ResponseErrorUnauthorized","required":["Unauthorized"],"properties":{"Unauthorized":{"type":"string"}}},{"type":"object","title":"ResponseErrorBadRequest","required":["BadRequest"],"properties":{"BadRequest":{"type":"string"}}},{"type":"object","title":"ResponseErrorForbidden","required":["Forbidden"],"properties":{"Forbidden":{"type":"string"}}},{"type":"object","title":"ResponseErrorTemplateError","required":["TemplateError"],"properties":{"TemplateError":{"$ref":"#/components/schemas/ErrorTemplate"}}}]},"ResponseResult":{"oneOf":[{"type":"string","title":"ResponseResultHealth","enum":["Health"]},{"type":"object","title":"ResponseResultFlistCreated","required":["FlistCreated"],"properties":{"FlistCreated":{"$ref":"#/components/schemas/Job"}}},{"type":"object","title":"ResponseResultFlistState","required":["FlistState"],"properties":{"FlistState":{"$ref":"#/components/schemas/FlistState"}}},{"type":"object","title":"ResponseResultFlists","required":["Flists"],"properties":{"Flists":{"type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/FileInfo"}}}}},{"type":"object","title":"ResponseResultPreviewFlist","required":["PreviewFlist"],"properties":{"PreviewFlist":{"$ref":"#/components/schemas/PreviewResponse"}}},{"type":"object","title":"ResponseResultSignedIn","required":["SignedIn"],"properties":{"SignedIn":{"$ref":"#/components/schemas/SignInResponse"}}},{"type":"object","title":"ResponseResultDirTemplate","required":["DirTemplate"],"properties":{"DirTemplate":{"$ref":"#/components/schemas/DirListTemplate"}}},{"type":"object","title":"ResponseResultBlockUploaded","required":["BlockUploaded"],"properties":{"BlockUploaded":{"type":"string"}}},{"type":"object","title":"ResponseResultFileUploaded","required":["FileUploaded"],"properties":{"FileUploaded":{"$ref":"#/components/schemas/FileUploadResponse"}}},{"type":"object","title":"ResponseResultRes","required":["Res"],"properties":{"Res":{"type":"string","format":"binary"}}}]},"SignInBody":{"type":"object","required":["username","password"],"properties":{"password":{"type":"string"},"username":{"type":"string"}}},"SignInResponse":{"type":"object","required":["access_token"],"properties":{"access_token":{"type":"string"}}},"TemplateErr":{"oneOf":[{"type":"object","title":"TemplateErrBadRequest","required":["BadRequest"],"properties":{"BadRequest":{"type":"string"}}},{"type":"object","title":"TemplateErrNotFound","required":["NotFound"],"properties":{"NotFound":{"type":"string"}}},{"type":"object","title":"TemplateErrInternalServerError","required":["InternalServerError"],"properties":{"InternalServerError":{"type":"string"}}}]},"UploadBlockParams":{"type":"object","description":"Query parameters for uploading a block","required":["file_hash","idx"],"properties":{"file_hash":{"type":"string","description":"File hash associated with the block"},"idx":{"type":"integer","format":"int64","description":"Block index within the file","minimum":0}}},"UserBlocksResponse":{"type":"object","description":"Response for user blocks endpoint","required":["blocks","total","all_blocks"],"properties":{"all_blocks":{"type":"integer","format":"int64","description":"Total number of all blocks","minimum":0},"blocks":{"type":"array","items":{"$ref":"#/components/schemas/BlockInfo"},"description":"List of blocks with their indices"},"total":{"type":"integer","format":"int64","description":"Total number of blocks","minimum":0}}},"VerifyBlock":{"type":"object","description":"Request to verify if multiple blocks exist on the server","required":["block_hash","file_hash","block_index"],"properties":{"block_hash":{"type":"string","description":"Block hash to verify"},"block_index":{"type":"integer","format":"int64","description":"Block index within the file","minimum":0},"file_hash":{"type":"string","description":"File hash associated with the block"}}},"VerifyBlocksRequest":{"type":"object","required":["blocks"],"properties":{"blocks":{"type":"array","items":{"$ref":"#/components/schemas/VerifyBlock"},"description":"List of blocks to verify"}}},"VerifyBlocksResponse":{"type":"object","description":"Response with list of missing blocks","required":["missing"],"properties":{"missing":{"type":"array","items":{"type":"string"},"description":"List of block hashes that are missing on the server"}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}}},"tags":[{"name":"System","description":"System health and status"},{"name":"Authentication","description":"Authentication endpoints"},{"name":"Flist Management","description":"Flist creation and management"},{"name":"Block Management","description":"Block storage and retrieval"},{"name":"File Management","description":"File upload and download"},{"name":"Website Serving","description":"Website content serving"}]} \ No newline at end of file diff --git a/rfs-client/openapi/.gitignore b/rfs-client/openapi/.gitignore new file mode 100644 index 0000000..6aa1064 --- /dev/null +++ b/rfs-client/openapi/.gitignore @@ -0,0 +1,3 @@ +/target/ +**/*.rs.bk +Cargo.lock diff --git a/rfs-client/openapi/.openapi-generator-ignore b/rfs-client/openapi/.openapi-generator-ignore new file mode 100644 index 0000000..7484ee5 --- /dev/null +++ b/rfs-client/openapi/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/rfs-client/openapi/.openapi-generator/FILES b/rfs-client/openapi/.openapi-generator/FILES new file mode 100644 index 0000000..76dc4cd --- /dev/null +++ b/rfs-client/openapi/.openapi-generator/FILES @@ -0,0 +1,123 @@ +.gitignore +.travis.yml +Cargo.toml +README.md +docs/AuthenticationApi.md +docs/BlockDownloadsResponse.md +docs/BlockInfo.md +docs/BlockManagementApi.md +docs/BlockUploadedResponse.md +docs/BlocksResponse.md +docs/DirListTemplate.md +docs/DirLister.md +docs/ErrorTemplate.md +docs/FileDownloadRequest.md +docs/FileInfo.md +docs/FileManagementApi.md +docs/FileUploadResponse.md +docs/FlistBody.md +docs/FlistManagementApi.md +docs/FlistState.md +docs/FlistStateAccepted.md +docs/FlistStateCreated.md +docs/FlistStateInProgress.md +docs/FlistStateInfo.md +docs/FlistStateResponse.md +docs/FlistStateStarted.md +docs/HealthResponse.md +docs/Job.md +docs/ListBlocksParams.md +docs/ListBlocksResponse.md +docs/PreviewResponse.md +docs/ResponseError.md +docs/ResponseErrorBadRequest.md +docs/ResponseErrorConflict.md +docs/ResponseErrorForbidden.md +docs/ResponseErrorNotFound.md +docs/ResponseErrorTemplateError.md +docs/ResponseErrorUnauthorized.md +docs/ResponseResult.md +docs/ResponseResultBlockUploaded.md +docs/ResponseResultDirTemplate.md +docs/ResponseResultFileUploaded.md +docs/ResponseResultFlistCreated.md +docs/ResponseResultFlistState.md +docs/ResponseResultFlists.md +docs/ResponseResultPreviewFlist.md +docs/ResponseResultRes.md +docs/ResponseResultSignedIn.md +docs/SignInBody.md +docs/SignInResponse.md +docs/SystemApi.md +docs/TemplateErr.md +docs/TemplateErrBadRequest.md +docs/TemplateErrInternalServerError.md +docs/TemplateErrNotFound.md +docs/UploadBlockParams.md +docs/UserBlocksResponse.md +docs/VerifyBlock.md +docs/VerifyBlocksRequest.md +docs/VerifyBlocksResponse.md +docs/WebsiteServingApi.md +git_push.sh +src/apis/authentication_api.rs +src/apis/block_management_api.rs +src/apis/configuration.rs +src/apis/file_management_api.rs +src/apis/flist_management_api.rs +src/apis/mod.rs +src/apis/system_api.rs +src/apis/website_serving_api.rs +src/lib.rs +src/models/block_downloads_response.rs +src/models/block_info.rs +src/models/block_uploaded_response.rs +src/models/blocks_response.rs +src/models/dir_list_template.rs +src/models/dir_lister.rs +src/models/error_template.rs +src/models/file_download_request.rs +src/models/file_info.rs +src/models/file_upload_response.rs +src/models/flist_body.rs +src/models/flist_state.rs +src/models/flist_state_accepted.rs +src/models/flist_state_created.rs +src/models/flist_state_in_progress.rs +src/models/flist_state_info.rs +src/models/flist_state_response.rs +src/models/flist_state_started.rs +src/models/health_response.rs +src/models/job.rs +src/models/list_blocks_params.rs +src/models/list_blocks_response.rs +src/models/mod.rs +src/models/preview_response.rs +src/models/response_error.rs +src/models/response_error_bad_request.rs +src/models/response_error_conflict.rs +src/models/response_error_forbidden.rs +src/models/response_error_not_found.rs +src/models/response_error_template_error.rs +src/models/response_error_unauthorized.rs +src/models/response_result.rs +src/models/response_result_block_uploaded.rs +src/models/response_result_dir_template.rs +src/models/response_result_file_uploaded.rs +src/models/response_result_flist_created.rs +src/models/response_result_flist_state.rs +src/models/response_result_flists.rs +src/models/response_result_preview_flist.rs +src/models/response_result_res.rs +src/models/response_result_signed_in.rs +src/models/sign_in_body.rs +src/models/sign_in_response.rs +src/models/template_err.rs +src/models/template_err_bad_request.rs +src/models/template_err_internal_server_error.rs +src/models/template_err_not_found.rs +src/models/upload_block_params.rs +src/models/user_blocks_response.rs +src/models/verify_block.rs +src/models/verify_blocks_request.rs +src/models/verify_blocks_response.rs diff --git a/rfs-client/openapi/.openapi-generator/VERSION b/rfs-client/openapi/.openapi-generator/VERSION new file mode 100644 index 0000000..eb1dc6a --- /dev/null +++ b/rfs-client/openapi/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.13.0 diff --git a/rfs-client/openapi/.travis.yml b/rfs-client/openapi/.travis.yml new file mode 100644 index 0000000..22761ba --- /dev/null +++ b/rfs-client/openapi/.travis.yml @@ -0,0 +1 @@ +language: rust diff --git a/rfs-client/openapi/Cargo.toml b/rfs-client/openapi/Cargo.toml new file mode 100644 index 0000000..e440338 --- /dev/null +++ b/rfs-client/openapi/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "openapi" +version = "0.2.0" +authors = ["OpenAPI Generator team and contributors"] +description = "No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)" +license = "" +edition = "2021" + +[dependencies] +serde = { version = "^1.0", features = ["derive"] } +serde_with = { version = "^3.8", default-features = false, features = ["base64", "std", "macros"] } +serde_json = "^1.0" +serde_repr = "^0.1" +url = "^2.5" +reqwest = { version = "^0.12", default-features = false, features = ["json", "multipart"] } diff --git a/rfs-client/openapi/README.md b/rfs-client/openapi/README.md new file mode 100644 index 0000000..ec95d95 --- /dev/null +++ b/rfs-client/openapi/README.md @@ -0,0 +1,113 @@ +# Rust API client for openapi + +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + + +## Overview + +This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://openapis.org) from a remote server, you can easily generate an API client. + +- API version: 0.2.0 +- Package version: 0.2.0 +- Generator version: 7.13.0 +- Build package: `org.openapitools.codegen.languages.RustClientCodegen` + +## Installation + +Put the package under your project folder in a directory named `openapi` and add the following to `Cargo.toml` under `[dependencies]`: + +``` +openapi = { path = "./openapi" } +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*AuthenticationApi* | [**sign_in_handler**](docs/AuthenticationApi.md#sign_in_handler) | **POST** /api/v1/signin | +*BlockManagementApi* | [**check_block_handler**](docs/BlockManagementApi.md#check_block_handler) | **HEAD** /api/v1/block/{hash} | Checks a block by its hash. +*BlockManagementApi* | [**get_block_downloads_handler**](docs/BlockManagementApi.md#get_block_downloads_handler) | **GET** /api/v1/block/{hash}/downloads | Retrieve the number of times a block has been downloaded. +*BlockManagementApi* | [**get_block_handler**](docs/BlockManagementApi.md#get_block_handler) | **GET** /api/v1/block/{hash} | Retrieve a block by its hash. +*BlockManagementApi* | [**get_blocks_by_hash_handler**](docs/BlockManagementApi.md#get_blocks_by_hash_handler) | **GET** /api/v1/blocks/{hash} | Retrieve blocks by hash (file hash or block hash). +*BlockManagementApi* | [**get_user_blocks_handler**](docs/BlockManagementApi.md#get_user_blocks_handler) | **GET** /api/v1/user/blocks | Retrieve all blocks uploaded by a specific user. +*BlockManagementApi* | [**list_blocks_handler**](docs/BlockManagementApi.md#list_blocks_handler) | **GET** /api/v1/blocks | List all block hashes in the server with pagination +*BlockManagementApi* | [**upload_block_handler**](docs/BlockManagementApi.md#upload_block_handler) | **POST** /api/v1/block | Upload a block to the server. +*BlockManagementApi* | [**verify_blocks_handler**](docs/BlockManagementApi.md#verify_blocks_handler) | **POST** /api/v1/block/verify | Verify if multiple blocks exist on the server. +*FileManagementApi* | [**get_file_handler**](docs/FileManagementApi.md#get_file_handler) | **GET** /api/v1/file/{hash} | Retrieve a file by its hash from path, with optional custom filename in request body. +*FileManagementApi* | [**upload_file_handler**](docs/FileManagementApi.md#upload_file_handler) | **POST** /api/v1/file | Upload a file to the server. +*FlistManagementApi* | [**create_flist_handler**](docs/FlistManagementApi.md#create_flist_handler) | **POST** /api/v1/fl | +*FlistManagementApi* | [**get_flist_state_handler**](docs/FlistManagementApi.md#get_flist_state_handler) | **GET** /api/v1/fl/{job_id} | +*FlistManagementApi* | [**list_flists_handler**](docs/FlistManagementApi.md#list_flists_handler) | **GET** /api/v1/fl | +*FlistManagementApi* | [**preview_flist_handler**](docs/FlistManagementApi.md#preview_flist_handler) | **GET** /api/v1/fl/preview/{flist_path} | +*FlistManagementApi* | [**serve_flists**](docs/FlistManagementApi.md#serve_flists) | **GET** /{path} | Serve flist files from the server's filesystem +*SystemApi* | [**health_check_handler**](docs/SystemApi.md#health_check_handler) | **GET** /api/v1 | +*WebsiteServingApi* | [**serve_website_handler**](docs/WebsiteServingApi.md#serve_website_handler) | **GET** /api/v1/website/{website_hash}/{path} | + + +## Documentation For Models + + - [BlockDownloadsResponse](docs/BlockDownloadsResponse.md) + - [BlockInfo](docs/BlockInfo.md) + - [BlockUploadedResponse](docs/BlockUploadedResponse.md) + - [BlocksResponse](docs/BlocksResponse.md) + - [DirListTemplate](docs/DirListTemplate.md) + - [DirLister](docs/DirLister.md) + - [ErrorTemplate](docs/ErrorTemplate.md) + - [FileDownloadRequest](docs/FileDownloadRequest.md) + - [FileInfo](docs/FileInfo.md) + - [FileUploadResponse](docs/FileUploadResponse.md) + - [FlistBody](docs/FlistBody.md) + - [FlistState](docs/FlistState.md) + - [FlistStateAccepted](docs/FlistStateAccepted.md) + - [FlistStateCreated](docs/FlistStateCreated.md) + - [FlistStateInProgress](docs/FlistStateInProgress.md) + - [FlistStateInfo](docs/FlistStateInfo.md) + - [FlistStateResponse](docs/FlistStateResponse.md) + - [FlistStateStarted](docs/FlistStateStarted.md) + - [HealthResponse](docs/HealthResponse.md) + - [Job](docs/Job.md) + - [ListBlocksParams](docs/ListBlocksParams.md) + - [ListBlocksResponse](docs/ListBlocksResponse.md) + - [PreviewResponse](docs/PreviewResponse.md) + - [ResponseError](docs/ResponseError.md) + - [ResponseErrorBadRequest](docs/ResponseErrorBadRequest.md) + - [ResponseErrorConflict](docs/ResponseErrorConflict.md) + - [ResponseErrorForbidden](docs/ResponseErrorForbidden.md) + - [ResponseErrorNotFound](docs/ResponseErrorNotFound.md) + - [ResponseErrorTemplateError](docs/ResponseErrorTemplateError.md) + - [ResponseErrorUnauthorized](docs/ResponseErrorUnauthorized.md) + - [ResponseResult](docs/ResponseResult.md) + - [ResponseResultBlockUploaded](docs/ResponseResultBlockUploaded.md) + - [ResponseResultDirTemplate](docs/ResponseResultDirTemplate.md) + - [ResponseResultFileUploaded](docs/ResponseResultFileUploaded.md) + - [ResponseResultFlistCreated](docs/ResponseResultFlistCreated.md) + - [ResponseResultFlistState](docs/ResponseResultFlistState.md) + - [ResponseResultFlists](docs/ResponseResultFlists.md) + - [ResponseResultPreviewFlist](docs/ResponseResultPreviewFlist.md) + - [ResponseResultRes](docs/ResponseResultRes.md) + - [ResponseResultSignedIn](docs/ResponseResultSignedIn.md) + - [SignInBody](docs/SignInBody.md) + - [SignInResponse](docs/SignInResponse.md) + - [TemplateErr](docs/TemplateErr.md) + - [TemplateErrBadRequest](docs/TemplateErrBadRequest.md) + - [TemplateErrInternalServerError](docs/TemplateErrInternalServerError.md) + - [TemplateErrNotFound](docs/TemplateErrNotFound.md) + - [UploadBlockParams](docs/UploadBlockParams.md) + - [UserBlocksResponse](docs/UserBlocksResponse.md) + - [VerifyBlock](docs/VerifyBlock.md) + - [VerifyBlocksRequest](docs/VerifyBlocksRequest.md) + - [VerifyBlocksResponse](docs/VerifyBlocksResponse.md) + + +To get access to the crate's generated documentation, use: + +``` +cargo doc --open +``` + +## Author + + + diff --git a/rfs-client/openapi/docs/AuthenticationApi.md b/rfs-client/openapi/docs/AuthenticationApi.md new file mode 100644 index 0000000..553ea8e --- /dev/null +++ b/rfs-client/openapi/docs/AuthenticationApi.md @@ -0,0 +1,37 @@ +# \AuthenticationApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**sign_in_handler**](AuthenticationApi.md#sign_in_handler) | **POST** /api/v1/signin | + + + +## sign_in_handler + +> models::SignInResponse sign_in_handler(sign_in_body) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**sign_in_body** | [**SignInBody**](SignInBody.md) | | [required] | + +### Return type + +[**models::SignInResponse**](SignInResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/rfs-client/openapi/docs/Block.md b/rfs-client/openapi/docs/Block.md new file mode 100644 index 0000000..9e187d8 --- /dev/null +++ b/rfs-client/openapi/docs/Block.md @@ -0,0 +1,14 @@ +# Block + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**data** | [**std::path::PathBuf**](std::path::PathBuf.md) | | +**hash** | **String** | | +**index** | **i64** | | +**size** | **i32** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/BlockDownloadsResponse.md b/rfs-client/openapi/docs/BlockDownloadsResponse.md new file mode 100644 index 0000000..ed00823 --- /dev/null +++ b/rfs-client/openapi/docs/BlockDownloadsResponse.md @@ -0,0 +1,13 @@ +# BlockDownloadsResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**block_hash** | **String** | Block hash | +**block_size** | **i64** | Size of the block in bytes | +**downloads_count** | **i64** | Number of times the block has been downloaded | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/BlockInfo.md b/rfs-client/openapi/docs/BlockInfo.md new file mode 100644 index 0000000..040582f --- /dev/null +++ b/rfs-client/openapi/docs/BlockInfo.md @@ -0,0 +1,12 @@ +# BlockInfo + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**hash** | **String** | Block hash | +**index** | **i64** | Block index within the file | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/BlockManagementApi.md b/rfs-client/openapi/docs/BlockManagementApi.md new file mode 100644 index 0000000..5e07519 --- /dev/null +++ b/rfs-client/openapi/docs/BlockManagementApi.md @@ -0,0 +1,250 @@ +# \BlockManagementApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**check_block_handler**](BlockManagementApi.md#check_block_handler) | **HEAD** /api/v1/block/{hash} | Checks a block by its hash. +[**get_block_downloads_handler**](BlockManagementApi.md#get_block_downloads_handler) | **GET** /api/v1/block/{hash}/downloads | Retrieve the number of times a block has been downloaded. +[**get_block_handler**](BlockManagementApi.md#get_block_handler) | **GET** /api/v1/block/{hash} | Retrieve a block by its hash. +[**get_blocks_by_hash_handler**](BlockManagementApi.md#get_blocks_by_hash_handler) | **GET** /api/v1/blocks/{hash} | Retrieve blocks by hash (file hash or block hash). +[**get_user_blocks_handler**](BlockManagementApi.md#get_user_blocks_handler) | **GET** /api/v1/user/blocks | Retrieve all blocks uploaded by a specific user. +[**list_blocks_handler**](BlockManagementApi.md#list_blocks_handler) | **GET** /api/v1/blocks | List all block hashes in the server with pagination +[**upload_block_handler**](BlockManagementApi.md#upload_block_handler) | **POST** /api/v1/block | Upload a block to the server. +[**verify_blocks_handler**](BlockManagementApi.md#verify_blocks_handler) | **POST** /api/v1/block/verify | Verify if multiple blocks exist on the server. + + + +## check_block_handler + +> check_block_handler(hash) +Checks a block by its hash. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**hash** | **String** | Block hash | [required] | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## get_block_downloads_handler + +> models::BlockDownloadsResponse get_block_downloads_handler(hash) +Retrieve the number of times a block has been downloaded. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**hash** | **String** | Block hash | [required] | + +### Return type + +[**models::BlockDownloadsResponse**](BlockDownloadsResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## get_block_handler + +> std::path::PathBuf get_block_handler(hash) +Retrieve a block by its hash. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**hash** | **String** | Block hash | [required] | + +### Return type + +[**std::path::PathBuf**](std::path::PathBuf.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/octet-stream, application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## get_blocks_by_hash_handler + +> models::BlocksResponse get_blocks_by_hash_handler(hash) +Retrieve blocks by hash (file hash or block hash). + +If the hash is a file hash, returns all blocks with their block index related to that file. If the hash is a block hash, returns the block itself. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**hash** | **String** | File hash or block hash | [required] | + +### Return type + +[**models::BlocksResponse**](BlocksResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## get_user_blocks_handler + +> models::UserBlocksResponse get_user_blocks_handler(page, per_page) +Retrieve all blocks uploaded by a specific user. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**page** | Option<**i32**> | Page number (1-indexed) | | +**per_page** | Option<**i32**> | Number of items per page | | + +### Return type + +[**models::UserBlocksResponse**](UserBlocksResponse.md) + +### Authorization + +[bearerAuth](../README.md#bearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## list_blocks_handler + +> models::ListBlocksResponse list_blocks_handler(page, per_page) +List all block hashes in the server with pagination + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**page** | Option<**i32**> | Page number (1-indexed) | | +**per_page** | Option<**i32**> | Number of items per page | | + +### Return type + +[**models::ListBlocksResponse**](ListBlocksResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## upload_block_handler + +> models::BlockUploadedResponse upload_block_handler(file_hash, idx, body) +Upload a block to the server. + +If the block already exists, the server will return a 200 OK response. If the block is new, the server will return a 201 Created response. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**file_hash** | **String** | File hash associated with the block | [required] | +**idx** | **i64** | Block index within the file | [required] | +**body** | **std::path::PathBuf** | Block data to upload | [required] | + +### Return type + +[**models::BlockUploadedResponse**](BlockUploadedResponse.md) + +### Authorization + +[bearerAuth](../README.md#bearerAuth) + +### HTTP request headers + +- **Content-Type**: application/octet-stream +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## verify_blocks_handler + +> models::VerifyBlocksResponse verify_blocks_handler(verify_blocks_request) +Verify if multiple blocks exist on the server. + +Returns a list of missing blocks. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**verify_blocks_request** | [**VerifyBlocksRequest**](VerifyBlocksRequest.md) | List of block hashes to verify | [required] | + +### Return type + +[**models::VerifyBlocksResponse**](VerifyBlocksResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/rfs-client/openapi/docs/BlockUploadedResponse.md b/rfs-client/openapi/docs/BlockUploadedResponse.md new file mode 100644 index 0000000..299460e --- /dev/null +++ b/rfs-client/openapi/docs/BlockUploadedResponse.md @@ -0,0 +1,12 @@ +# BlockUploadedResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**hash** | **String** | | +**message** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/BlocksResponse.md b/rfs-client/openapi/docs/BlocksResponse.md new file mode 100644 index 0000000..186a902 --- /dev/null +++ b/rfs-client/openapi/docs/BlocksResponse.md @@ -0,0 +1,11 @@ +# BlocksResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**blocks** | [**Vec**](BlockInfo.md) | List of blocks with their indices | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/DirListTemplate.md b/rfs-client/openapi/docs/DirListTemplate.md new file mode 100644 index 0000000..18ac940 --- /dev/null +++ b/rfs-client/openapi/docs/DirListTemplate.md @@ -0,0 +1,12 @@ +# DirListTemplate + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**cur_path** | **String** | | +**lister** | [**models::DirLister**](DirLister.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/DirLister.md b/rfs-client/openapi/docs/DirLister.md new file mode 100644 index 0000000..e49af50 --- /dev/null +++ b/rfs-client/openapi/docs/DirLister.md @@ -0,0 +1,11 @@ +# DirLister + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**files** | [**Vec**](FileInfo.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ErrorTemplate.md b/rfs-client/openapi/docs/ErrorTemplate.md new file mode 100644 index 0000000..e4ae2d9 --- /dev/null +++ b/rfs-client/openapi/docs/ErrorTemplate.md @@ -0,0 +1,13 @@ +# ErrorTemplate + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**cur_path** | **String** | | +**err** | [**models::TemplateErr**](TemplateErr.md) | | +**message** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/File.md b/rfs-client/openapi/docs/File.md new file mode 100644 index 0000000..b748494 --- /dev/null +++ b/rfs-client/openapi/docs/File.md @@ -0,0 +1,12 @@ +# File + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**file_content** | [**std::path::PathBuf**](std::path::PathBuf.md) | | +**file_hash** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/FileDownloadRequest.md b/rfs-client/openapi/docs/FileDownloadRequest.md new file mode 100644 index 0000000..5ed5929 --- /dev/null +++ b/rfs-client/openapi/docs/FileDownloadRequest.md @@ -0,0 +1,11 @@ +# FileDownloadRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**file_name** | **String** | The custom filename to use for download | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/FileInfo.md b/rfs-client/openapi/docs/FileInfo.md new file mode 100644 index 0000000..41ae74b --- /dev/null +++ b/rfs-client/openapi/docs/FileInfo.md @@ -0,0 +1,16 @@ +# FileInfo + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**is_file** | **bool** | | +**last_modified** | **i64** | | +**name** | **String** | | +**path_uri** | **String** | | +**progress** | **f32** | | +**size** | **i64** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/FileManagementApi.md b/rfs-client/openapi/docs/FileManagementApi.md new file mode 100644 index 0000000..8371065 --- /dev/null +++ b/rfs-client/openapi/docs/FileManagementApi.md @@ -0,0 +1,71 @@ +# \FileManagementApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_file_handler**](FileManagementApi.md#get_file_handler) | **GET** /api/v1/file/{hash} | Retrieve a file by its hash from path, with optional custom filename in request body. +[**upload_file_handler**](FileManagementApi.md#upload_file_handler) | **POST** /api/v1/file | Upload a file to the server. + + + +## get_file_handler + +> std::path::PathBuf get_file_handler(hash, file_download_request) +Retrieve a file by its hash from path, with optional custom filename in request body. + +The file will be reconstructed from its blocks. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**hash** | **String** | File hash | [required] | +**file_download_request** | [**FileDownloadRequest**](FileDownloadRequest.md) | Optional custom filename for download | [required] | + +### Return type + +[**std::path::PathBuf**](std::path::PathBuf.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/octet-stream, application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## upload_file_handler + +> models::FileUploadResponse upload_file_handler(body) +Upload a file to the server. + +The file will be split into blocks and stored in the database. + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**body** | **std::path::PathBuf** | File data to upload | [required] | + +### Return type + +[**models::FileUploadResponse**](FileUploadResponse.md) + +### Authorization + +[bearerAuth](../README.md#bearerAuth) + +### HTTP request headers + +- **Content-Type**: application/octet-stream +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/rfs-client/openapi/docs/FileUploadResponse.md b/rfs-client/openapi/docs/FileUploadResponse.md new file mode 100644 index 0000000..1b596ed --- /dev/null +++ b/rfs-client/openapi/docs/FileUploadResponse.md @@ -0,0 +1,12 @@ +# FileUploadResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**file_hash** | **String** | The file hash | +**message** | **String** | Message indicating success | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/FlistBody.md b/rfs-client/openapi/docs/FlistBody.md new file mode 100644 index 0000000..031819c --- /dev/null +++ b/rfs-client/openapi/docs/FlistBody.md @@ -0,0 +1,18 @@ +# FlistBody + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**auth** | Option<**String**> | | [optional] +**email** | Option<**String**> | | [optional] +**identity_token** | Option<**String**> | | [optional] +**image_name** | **String** | | +**password** | Option<**String**> | | [optional] +**registry_token** | Option<**String**> | | [optional] +**server_address** | Option<**String**> | | [optional] +**username** | Option<**String**> | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/FlistManagementApi.md b/rfs-client/openapi/docs/FlistManagementApi.md new file mode 100644 index 0000000..9a02de6 --- /dev/null +++ b/rfs-client/openapi/docs/FlistManagementApi.md @@ -0,0 +1,150 @@ +# \FlistManagementApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**create_flist_handler**](FlistManagementApi.md#create_flist_handler) | **POST** /api/v1/fl | +[**get_flist_state_handler**](FlistManagementApi.md#get_flist_state_handler) | **GET** /api/v1/fl/{job_id} | +[**list_flists_handler**](FlistManagementApi.md#list_flists_handler) | **GET** /api/v1/fl | +[**preview_flist_handler**](FlistManagementApi.md#preview_flist_handler) | **GET** /api/v1/fl/preview/{flist_path} | +[**serve_flists**](FlistManagementApi.md#serve_flists) | **GET** /{path} | Serve flist files from the server's filesystem + + + +## create_flist_handler + +> models::Job create_flist_handler(flist_body) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**flist_body** | [**FlistBody**](FlistBody.md) | | [required] | + +### Return type + +[**models::Job**](Job.md) + +### Authorization + +[bearerAuth](../README.md#bearerAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## get_flist_state_handler + +> models::FlistStateResponse get_flist_state_handler(job_id) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**job_id** | **String** | flist job id | [required] | + +### Return type + +[**models::FlistStateResponse**](FlistStateResponse.md) + +### Authorization + +[bearerAuth](../README.md#bearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## list_flists_handler + +> std::collections::HashMap> list_flists_handler() + + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +[**std::collections::HashMap>**](Vec.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## preview_flist_handler + +> models::PreviewResponse preview_flist_handler(flist_path) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**flist_path** | **String** | flist file path | [required] | + +### Return type + +[**models::PreviewResponse**](PreviewResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + + +## serve_flists + +> std::path::PathBuf serve_flists(path) +Serve flist files from the server's filesystem + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**path** | **String** | Path to the flist file or directory to serve | [required] | + +### Return type + +[**std::path::PathBuf**](std::path::PathBuf.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/octet-stream, application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/rfs-client/openapi/docs/FlistServingApi.md b/rfs-client/openapi/docs/FlistServingApi.md new file mode 100644 index 0000000..7896606 --- /dev/null +++ b/rfs-client/openapi/docs/FlistServingApi.md @@ -0,0 +1,37 @@ +# \FlistServingApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**serve_flists**](FlistServingApi.md#serve_flists) | **GET** /{path} | Serve flist files from the server's filesystem + + + +## serve_flists + +> models::ResponseResult serve_flists(path) +Serve flist files from the server's filesystem + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**path** | **String** | Path to the flist file or directory to serve | [required] | + +### Return type + +[**models::ResponseResult**](ResponseResult.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/rfs-client/openapi/docs/FlistState.md b/rfs-client/openapi/docs/FlistState.md new file mode 100644 index 0000000..c293503 --- /dev/null +++ b/rfs-client/openapi/docs/FlistState.md @@ -0,0 +1,15 @@ +# FlistState + +## Enum Variants + +| Name | Description | +|---- | -----| +| FlistStateAccepted | | +| FlistStateCreated | | +| FlistStateInProgress | | +| FlistStateStarted | | +| String | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/FlistStateAccepted.md b/rfs-client/openapi/docs/FlistStateAccepted.md new file mode 100644 index 0000000..aa72a0d --- /dev/null +++ b/rfs-client/openapi/docs/FlistStateAccepted.md @@ -0,0 +1,11 @@ +# FlistStateAccepted + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**accepted** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/FlistStateCreated.md b/rfs-client/openapi/docs/FlistStateCreated.md new file mode 100644 index 0000000..0987ac5 --- /dev/null +++ b/rfs-client/openapi/docs/FlistStateCreated.md @@ -0,0 +1,11 @@ +# FlistStateCreated + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**created** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/FlistStateInProgress.md b/rfs-client/openapi/docs/FlistStateInProgress.md new file mode 100644 index 0000000..f807e1b --- /dev/null +++ b/rfs-client/openapi/docs/FlistStateInProgress.md @@ -0,0 +1,11 @@ +# FlistStateInProgress + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**in_progress** | [**models::FlistStateInfo**](FlistStateInfo.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/FlistStateInfo.md b/rfs-client/openapi/docs/FlistStateInfo.md new file mode 100644 index 0000000..24acbd9 --- /dev/null +++ b/rfs-client/openapi/docs/FlistStateInfo.md @@ -0,0 +1,12 @@ +# FlistStateInfo + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**msg** | **String** | | +**progress** | **f32** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/FlistStateResponse.md b/rfs-client/openapi/docs/FlistStateResponse.md new file mode 100644 index 0000000..04389cb --- /dev/null +++ b/rfs-client/openapi/docs/FlistStateResponse.md @@ -0,0 +1,11 @@ +# FlistStateResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**flist_state** | [**models::FlistState**](FlistState.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/FlistStateStarted.md b/rfs-client/openapi/docs/FlistStateStarted.md new file mode 100644 index 0000000..f94300a --- /dev/null +++ b/rfs-client/openapi/docs/FlistStateStarted.md @@ -0,0 +1,11 @@ +# FlistStateStarted + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**started** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/HealthResponse.md b/rfs-client/openapi/docs/HealthResponse.md new file mode 100644 index 0000000..15ba1da --- /dev/null +++ b/rfs-client/openapi/docs/HealthResponse.md @@ -0,0 +1,11 @@ +# HealthResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**msg** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/Job.md b/rfs-client/openapi/docs/Job.md new file mode 100644 index 0000000..9af09c8 --- /dev/null +++ b/rfs-client/openapi/docs/Job.md @@ -0,0 +1,11 @@ +# Job + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ListBlocksParams.md b/rfs-client/openapi/docs/ListBlocksParams.md new file mode 100644 index 0000000..0218301 --- /dev/null +++ b/rfs-client/openapi/docs/ListBlocksParams.md @@ -0,0 +1,12 @@ +# ListBlocksParams + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**page** | Option<**i32**> | Page number (1-indexed) | [optional][default to 1] +**per_page** | Option<**i32**> | Number of items per page | [optional][default to 50] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ListBlocksResponse.md b/rfs-client/openapi/docs/ListBlocksResponse.md new file mode 100644 index 0000000..c199400 --- /dev/null +++ b/rfs-client/openapi/docs/ListBlocksResponse.md @@ -0,0 +1,14 @@ +# ListBlocksResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**blocks** | **Vec** | List of block hashes | +**page** | **i32** | Current page number | +**per_page** | **i32** | Number of items per page | +**total** | **i64** | Total number of blocks | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/PreviewResponse.md b/rfs-client/openapi/docs/PreviewResponse.md new file mode 100644 index 0000000..51cf063 --- /dev/null +++ b/rfs-client/openapi/docs/PreviewResponse.md @@ -0,0 +1,13 @@ +# PreviewResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**checksum** | **String** | | +**content** | **Vec** | | +**metadata** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseError.md b/rfs-client/openapi/docs/ResponseError.md new file mode 100644 index 0000000..1f0866d --- /dev/null +++ b/rfs-client/openapi/docs/ResponseError.md @@ -0,0 +1,17 @@ +# ResponseError + +## Enum Variants + +| Name | Description | +|---- | -----| +| ResponseErrorBadRequest | | +| ResponseErrorConflict | | +| ResponseErrorForbidden | | +| ResponseErrorNotFound | | +| ResponseErrorTemplateError | | +| ResponseErrorUnauthorized | | +| String | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseErrorBadRequest.md b/rfs-client/openapi/docs/ResponseErrorBadRequest.md new file mode 100644 index 0000000..216498d --- /dev/null +++ b/rfs-client/openapi/docs/ResponseErrorBadRequest.md @@ -0,0 +1,11 @@ +# ResponseErrorBadRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**bad_request** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseErrorConflict.md b/rfs-client/openapi/docs/ResponseErrorConflict.md new file mode 100644 index 0000000..c21b5c1 --- /dev/null +++ b/rfs-client/openapi/docs/ResponseErrorConflict.md @@ -0,0 +1,11 @@ +# ResponseErrorConflict + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**conflict** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseErrorForbidden.md b/rfs-client/openapi/docs/ResponseErrorForbidden.md new file mode 100644 index 0000000..ee00a04 --- /dev/null +++ b/rfs-client/openapi/docs/ResponseErrorForbidden.md @@ -0,0 +1,11 @@ +# ResponseErrorForbidden + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**forbidden** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseErrorNotFound.md b/rfs-client/openapi/docs/ResponseErrorNotFound.md new file mode 100644 index 0000000..d137545 --- /dev/null +++ b/rfs-client/openapi/docs/ResponseErrorNotFound.md @@ -0,0 +1,11 @@ +# ResponseErrorNotFound + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**not_found** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseErrorTemplateError.md b/rfs-client/openapi/docs/ResponseErrorTemplateError.md new file mode 100644 index 0000000..20466c8 --- /dev/null +++ b/rfs-client/openapi/docs/ResponseErrorTemplateError.md @@ -0,0 +1,11 @@ +# ResponseErrorTemplateError + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**template_error** | [**models::ErrorTemplate**](ErrorTemplate.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseErrorUnauthorized.md b/rfs-client/openapi/docs/ResponseErrorUnauthorized.md new file mode 100644 index 0000000..c982e4a --- /dev/null +++ b/rfs-client/openapi/docs/ResponseErrorUnauthorized.md @@ -0,0 +1,11 @@ +# ResponseErrorUnauthorized + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**unauthorized** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseResult.md b/rfs-client/openapi/docs/ResponseResult.md new file mode 100644 index 0000000..1ddcb71 --- /dev/null +++ b/rfs-client/openapi/docs/ResponseResult.md @@ -0,0 +1,20 @@ +# ResponseResult + +## Enum Variants + +| Name | Description | +|---- | -----| +| ResponseResultBlockUploaded | | +| ResponseResultDirTemplate | | +| ResponseResultFileUploaded | | +| ResponseResultFlistCreated | | +| ResponseResultFlistState | | +| ResponseResultFlists | | +| ResponseResultPreviewFlist | | +| ResponseResultRes | | +| ResponseResultSignedIn | | +| String | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseResultBlockUploaded.md b/rfs-client/openapi/docs/ResponseResultBlockUploaded.md new file mode 100644 index 0000000..e1cb9ca --- /dev/null +++ b/rfs-client/openapi/docs/ResponseResultBlockUploaded.md @@ -0,0 +1,11 @@ +# ResponseResultBlockUploaded + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**block_uploaded** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseResultDirTemplate.md b/rfs-client/openapi/docs/ResponseResultDirTemplate.md new file mode 100644 index 0000000..74b2c33 --- /dev/null +++ b/rfs-client/openapi/docs/ResponseResultDirTemplate.md @@ -0,0 +1,11 @@ +# ResponseResultDirTemplate + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**dir_template** | [**models::DirListTemplate**](DirListTemplate.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseResultFileUploaded.md b/rfs-client/openapi/docs/ResponseResultFileUploaded.md new file mode 100644 index 0000000..741e8fb --- /dev/null +++ b/rfs-client/openapi/docs/ResponseResultFileUploaded.md @@ -0,0 +1,11 @@ +# ResponseResultFileUploaded + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**file_uploaded** | [**models::FileUploadResponse**](FileUploadResponse.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseResultFlistCreated.md b/rfs-client/openapi/docs/ResponseResultFlistCreated.md new file mode 100644 index 0000000..030f1ae --- /dev/null +++ b/rfs-client/openapi/docs/ResponseResultFlistCreated.md @@ -0,0 +1,11 @@ +# ResponseResultFlistCreated + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**flist_created** | [**models::Job**](Job.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseResultFlistState.md b/rfs-client/openapi/docs/ResponseResultFlistState.md new file mode 100644 index 0000000..c406eb4 --- /dev/null +++ b/rfs-client/openapi/docs/ResponseResultFlistState.md @@ -0,0 +1,11 @@ +# ResponseResultFlistState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**flist_state** | [**models::FlistState**](FlistState.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseResultFlists.md b/rfs-client/openapi/docs/ResponseResultFlists.md new file mode 100644 index 0000000..ceab34e --- /dev/null +++ b/rfs-client/openapi/docs/ResponseResultFlists.md @@ -0,0 +1,11 @@ +# ResponseResultFlists + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**flists** | [**std::collections::HashMap>**](Vec.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseResultPreviewFlist.md b/rfs-client/openapi/docs/ResponseResultPreviewFlist.md new file mode 100644 index 0000000..17c867e --- /dev/null +++ b/rfs-client/openapi/docs/ResponseResultPreviewFlist.md @@ -0,0 +1,11 @@ +# ResponseResultPreviewFlist + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**preview_flist** | [**models::PreviewResponse**](PreviewResponse.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseResultRes.md b/rfs-client/openapi/docs/ResponseResultRes.md new file mode 100644 index 0000000..4dacba1 --- /dev/null +++ b/rfs-client/openapi/docs/ResponseResultRes.md @@ -0,0 +1,11 @@ +# ResponseResultRes + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**res** | [**std::path::PathBuf**](std::path::PathBuf.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/ResponseResultSignedIn.md b/rfs-client/openapi/docs/ResponseResultSignedIn.md new file mode 100644 index 0000000..9b60037 --- /dev/null +++ b/rfs-client/openapi/docs/ResponseResultSignedIn.md @@ -0,0 +1,11 @@ +# ResponseResultSignedIn + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**signed_in** | [**models::SignInResponse**](SignInResponse.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/SignInBody.md b/rfs-client/openapi/docs/SignInBody.md new file mode 100644 index 0000000..65c2b20 --- /dev/null +++ b/rfs-client/openapi/docs/SignInBody.md @@ -0,0 +1,12 @@ +# SignInBody + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**password** | **String** | | +**username** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/SignInResponse.md b/rfs-client/openapi/docs/SignInResponse.md new file mode 100644 index 0000000..77dfa02 --- /dev/null +++ b/rfs-client/openapi/docs/SignInResponse.md @@ -0,0 +1,11 @@ +# SignInResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**access_token** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/SystemApi.md b/rfs-client/openapi/docs/SystemApi.md new file mode 100644 index 0000000..8e11bac --- /dev/null +++ b/rfs-client/openapi/docs/SystemApi.md @@ -0,0 +1,34 @@ +# \SystemApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**health_check_handler**](SystemApi.md#health_check_handler) | **GET** /api/v1 | + + + +## health_check_handler + +> models::HealthResponse health_check_handler() + + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +[**models::HealthResponse**](HealthResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/rfs-client/openapi/docs/TemplateErr.md b/rfs-client/openapi/docs/TemplateErr.md new file mode 100644 index 0000000..0423d47 --- /dev/null +++ b/rfs-client/openapi/docs/TemplateErr.md @@ -0,0 +1,13 @@ +# TemplateErr + +## Enum Variants + +| Name | Description | +|---- | -----| +| TemplateErrBadRequest | | +| TemplateErrInternalServerError | | +| TemplateErrNotFound | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/TemplateErrBadRequest.md b/rfs-client/openapi/docs/TemplateErrBadRequest.md new file mode 100644 index 0000000..4e04fdc --- /dev/null +++ b/rfs-client/openapi/docs/TemplateErrBadRequest.md @@ -0,0 +1,11 @@ +# TemplateErrBadRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**bad_request** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/TemplateErrInternalServerError.md b/rfs-client/openapi/docs/TemplateErrInternalServerError.md new file mode 100644 index 0000000..e71b010 --- /dev/null +++ b/rfs-client/openapi/docs/TemplateErrInternalServerError.md @@ -0,0 +1,11 @@ +# TemplateErrInternalServerError + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**internal_server_error** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/TemplateErrNotFound.md b/rfs-client/openapi/docs/TemplateErrNotFound.md new file mode 100644 index 0000000..a256aab --- /dev/null +++ b/rfs-client/openapi/docs/TemplateErrNotFound.md @@ -0,0 +1,11 @@ +# TemplateErrNotFound + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**not_found** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/UploadBlockParams.md b/rfs-client/openapi/docs/UploadBlockParams.md new file mode 100644 index 0000000..28893e4 --- /dev/null +++ b/rfs-client/openapi/docs/UploadBlockParams.md @@ -0,0 +1,12 @@ +# UploadBlockParams + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**file_hash** | **String** | File hash associated with the block | +**idx** | **i64** | Block index within the file | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/UserBlocksResponse.md b/rfs-client/openapi/docs/UserBlocksResponse.md new file mode 100644 index 0000000..05f7354 --- /dev/null +++ b/rfs-client/openapi/docs/UserBlocksResponse.md @@ -0,0 +1,13 @@ +# UserBlocksResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**all_blocks** | **i64** | Total number of all blocks | +**blocks** | [**Vec**](BlockInfo.md) | List of blocks with their indices | +**total** | **i64** | Total number of blocks | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/VerifyBlock.md b/rfs-client/openapi/docs/VerifyBlock.md new file mode 100644 index 0000000..38cb107 --- /dev/null +++ b/rfs-client/openapi/docs/VerifyBlock.md @@ -0,0 +1,13 @@ +# VerifyBlock + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**block_hash** | **String** | Block hash to verify | +**block_index** | **i64** | Block index within the file | +**file_hash** | **String** | File hash associated with the block | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/VerifyBlocksRequest.md b/rfs-client/openapi/docs/VerifyBlocksRequest.md new file mode 100644 index 0000000..830426d --- /dev/null +++ b/rfs-client/openapi/docs/VerifyBlocksRequest.md @@ -0,0 +1,11 @@ +# VerifyBlocksRequest + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**blocks** | [**Vec**](VerifyBlock.md) | List of blocks to verify | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/VerifyBlocksResponse.md b/rfs-client/openapi/docs/VerifyBlocksResponse.md new file mode 100644 index 0000000..807a3eb --- /dev/null +++ b/rfs-client/openapi/docs/VerifyBlocksResponse.md @@ -0,0 +1,11 @@ +# VerifyBlocksResponse + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**missing** | **Vec** | List of block hashes that are missing on the server | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/rfs-client/openapi/docs/WebsiteServingApi.md b/rfs-client/openapi/docs/WebsiteServingApi.md new file mode 100644 index 0000000..64d2997 --- /dev/null +++ b/rfs-client/openapi/docs/WebsiteServingApi.md @@ -0,0 +1,38 @@ +# \WebsiteServingApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**serve_website_handler**](WebsiteServingApi.md#serve_website_handler) | **GET** /api/v1/website/{website_hash}/{path} | + + + +## serve_website_handler + +> std::path::PathBuf serve_website_handler(website_hash, path) + + +### Parameters + + +Name | Type | Description | Required | Notes +------------- | ------------- | ------------- | ------------- | ------------- +**website_hash** | **String** | flist hash of the website directory | [required] | +**path** | **String** | Path to the file within the website directory, defaults to index.html if empty | [required] | + +### Return type + +[**std::path::PathBuf**](std::path::PathBuf.md) + +### Authorization + +No authorization required + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/octet-stream, application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/rfs-client/openapi/git_push.sh b/rfs-client/openapi/git_push.sh new file mode 100644 index 0000000..f53a75d --- /dev/null +++ b/rfs-client/openapi/git_push.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/rfs-client/openapi/src/apis/authentication_api.rs b/rfs-client/openapi/src/apis/authentication_api.rs new file mode 100644 index 0000000..bf43940 --- /dev/null +++ b/rfs-client/openapi/src/apis/authentication_api.rs @@ -0,0 +1,64 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + + +use reqwest; +use serde::{Deserialize, Serialize, de::Error as _}; +use crate::{apis::ResponseContent, models}; +use super::{Error, configuration, ContentType}; + + +/// struct for typed errors of method [`sign_in_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum SignInHandlerError { + Status401(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + + +pub async fn sign_in_handler(configuration: &configuration::Configuration, sign_in_body: models::SignInBody) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_sign_in_body = sign_in_body; + + let uri_str = format!("{}/api/v1/signin", configuration.base_path); + let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + req_builder = req_builder.json(&p_sign_in_body); + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SignInResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SignInResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + diff --git a/rfs-client/openapi/src/apis/block_management_api.rs b/rfs-client/openapi/src/apis/block_management_api.rs new file mode 100644 index 0000000..81390d1 --- /dev/null +++ b/rfs-client/openapi/src/apis/block_management_api.rs @@ -0,0 +1,385 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + + +use reqwest; +use serde::{Deserialize, Serialize, de::Error as _}; +use crate::{apis::ResponseContent, models}; +use super::{Error, configuration, ContentType}; + + +/// struct for typed errors of method [`check_block_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum CheckBlockHandlerError { + Status404(models::ResponseError), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`get_block_downloads_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetBlockDownloadsHandlerError { + Status404(), + Status500(), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`get_block_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetBlockHandlerError { + Status404(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`get_blocks_by_hash_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetBlocksByHashHandlerError { + Status404(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`get_user_blocks_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetUserBlocksHandlerError { + Status401(), + Status500(), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`list_blocks_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ListBlocksHandlerError { + Status400(), + Status500(), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`upload_block_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum UploadBlockHandlerError { + Status400(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`verify_blocks_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum VerifyBlocksHandlerError { + Status400(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + + +pub async fn check_block_handler(configuration: &configuration::Configuration, hash: &str) -> Result<(), Error> { + // add a prefix to parameters to efficiently prevent name collisions + let p_hash = hash; + + let uri_str = format!("{}/api/v1/block/{hash}", configuration.base_path, hash=crate::apis::urlencode(p_hash)); + let mut req_builder = configuration.client.request(reqwest::Method::HEAD, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + + if !status.is_client_error() && !status.is_server_error() { + Ok(()) + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +pub async fn get_block_downloads_handler(configuration: &configuration::Configuration, hash: &str) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_hash = hash; + + let uri_str = format!("{}/api/v1/block/{hash}/downloads", configuration.base_path, hash=crate::apis::urlencode(p_hash)); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BlockDownloadsResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BlockDownloadsResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +pub async fn get_block_handler(configuration: &configuration::Configuration, hash: &str) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_hash = hash; + + let uri_str = format!("{}/api/v1/block/{hash}", configuration.base_path, hash=crate::apis::urlencode(p_hash)); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + + if !status.is_client_error() && !status.is_server_error() { + Ok(resp) + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +/// If the hash is a file hash, returns all blocks with their block index related to that file. If the hash is a block hash, returns the block itself. +pub async fn get_blocks_by_hash_handler(configuration: &configuration::Configuration, hash: &str) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_hash = hash; + + let uri_str = format!("{}/api/v1/blocks/{hash}", configuration.base_path, hash=crate::apis::urlencode(p_hash)); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BlocksResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BlocksResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +pub async fn get_user_blocks_handler(configuration: &configuration::Configuration, page: Option, per_page: Option) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_page = page; + let p_per_page = per_page; + + let uri_str = format!("{}/api/v1/user/blocks", configuration.base_path); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref param_value) = p_page { + req_builder = req_builder.query(&[("page", ¶m_value.to_string())]); + } + if let Some(ref param_value) = p_per_page { + req_builder = req_builder.query(&[("per_page", ¶m_value.to_string())]); + } + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + if let Some(ref token) = configuration.bearer_access_token { + req_builder = req_builder.bearer_auth(token.to_owned()); + }; + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UserBlocksResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UserBlocksResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +pub async fn list_blocks_handler(configuration: &configuration::Configuration, page: Option, per_page: Option) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_page = page; + let p_per_page = per_page; + + let uri_str = format!("{}/api/v1/blocks", configuration.base_path); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref param_value) = p_page { + req_builder = req_builder.query(&[("page", ¶m_value.to_string())]); + } + if let Some(ref param_value) = p_per_page { + req_builder = req_builder.query(&[("per_page", ¶m_value.to_string())]); + } + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListBlocksResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListBlocksResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +/// If the block already exists, the server will return a 200 OK response. If the block is new, the server will return a 201 Created response. +pub async fn upload_block_handler(configuration: &configuration::Configuration, file_hash: &str, idx: i64, body: std::path::PathBuf) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_file_hash = file_hash; + let p_idx = idx; + let p_body = body; + + let uri_str = format!("{}/api/v1/block", configuration.base_path); + let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str); + + req_builder = req_builder.query(&[("file_hash", &p_file_hash.to_string())]); + req_builder = req_builder.query(&[("idx", &p_idx.to_string())]); + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + if let Some(ref token) = configuration.bearer_access_token { + req_builder = req_builder.bearer_auth(token.to_owned()); + }; + let file_content = std::fs::read(&p_body).map_err(|e| Error::Io(e))?; + req_builder = req_builder.body(file_content); + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BlockUploadedResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BlockUploadedResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +/// Returns a list of missing blocks. +pub async fn verify_blocks_handler(configuration: &configuration::Configuration, verify_blocks_request: models::VerifyBlocksRequest) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_verify_blocks_request = verify_blocks_request; + + let uri_str = format!("{}/api/v1/block/verify", configuration.base_path); + let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + req_builder = req_builder.json(&p_verify_blocks_request); + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::VerifyBlocksResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::VerifyBlocksResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + diff --git a/rfs-client/openapi/src/apis/configuration.rs b/rfs-client/openapi/src/apis/configuration.rs new file mode 100644 index 0000000..cb6d143 --- /dev/null +++ b/rfs-client/openapi/src/apis/configuration.rs @@ -0,0 +1,51 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + + + +#[derive(Debug, Clone)] +pub struct Configuration { + pub base_path: String, + pub user_agent: Option, + pub client: reqwest::Client, + pub basic_auth: Option, + pub oauth_access_token: Option, + pub bearer_access_token: Option, + pub api_key: Option, +} + +pub type BasicAuth = (String, Option); + +#[derive(Debug, Clone)] +pub struct ApiKey { + pub prefix: Option, + pub key: String, +} + + +impl Configuration { + pub fn new() -> Configuration { + Configuration::default() + } +} + +impl Default for Configuration { + fn default() -> Self { + Configuration { + base_path: "http://localhost".to_owned(), + user_agent: Some("OpenAPI-Generator/0.2.0/rust".to_owned()), + client: reqwest::Client::new(), + basic_auth: None, + oauth_access_token: None, + bearer_access_token: None, + api_key: None, + } + } +} diff --git a/rfs-client/openapi/src/apis/file_management_api.rs b/rfs-client/openapi/src/apis/file_management_api.rs new file mode 100644 index 0000000..7bb7515 --- /dev/null +++ b/rfs-client/openapi/src/apis/file_management_api.rs @@ -0,0 +1,106 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + + +use reqwest; +use serde::{Deserialize, Serialize, de::Error as _}; +use crate::{apis::ResponseContent, models}; +use super::{Error, configuration, ContentType}; + + +/// struct for typed errors of method [`get_file_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetFileHandlerError { + Status404(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`upload_file_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum UploadFileHandlerError { + Status400(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + + +/// The file will be reconstructed from its blocks. +pub async fn get_file_handler(configuration: &configuration::Configuration, hash: &str, file_download_request: models::FileDownloadRequest) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_hash = hash; + let p_file_download_request = file_download_request; + + let uri_str = format!("{}/api/v1/file/{hash}", configuration.base_path, hash=crate::apis::urlencode(p_hash)); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + req_builder = req_builder.json(&p_file_download_request); + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + + if !status.is_client_error() && !status.is_server_error() { + Ok(resp) + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +/// The file will be split into blocks and stored in the database. +pub async fn upload_file_handler(configuration: &configuration::Configuration, body: std::path::PathBuf) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_body = body; + + let uri_str = format!("{}/api/v1/file", configuration.base_path); + let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + if let Some(ref token) = configuration.bearer_access_token { + req_builder = req_builder.bearer_auth(token.to_owned()); + }; + let file_content = std::fs::read(&p_body).map_err(|e| Error::Io(e))?; + req_builder = req_builder.body(file_content); + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::FileUploadResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::FileUploadResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + diff --git a/rfs-client/openapi/src/apis/flist_management_api.rs b/rfs-client/openapi/src/apis/flist_management_api.rs new file mode 100644 index 0000000..81ce464 --- /dev/null +++ b/rfs-client/openapi/src/apis/flist_management_api.rs @@ -0,0 +1,244 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + + +use reqwest; +use serde::{Deserialize, Serialize, de::Error as _}; +use crate::{apis::ResponseContent, models}; +use super::{Error, configuration, ContentType}; + + +/// struct for typed errors of method [`create_flist_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum CreateFlistHandlerError { + Status401(models::ResponseError), + Status403(models::ResponseError), + Status409(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`get_flist_state_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetFlistStateHandlerError { + Status401(models::ResponseError), + Status403(models::ResponseError), + Status404(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`list_flists_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ListFlistsHandlerError { + Status401(models::ResponseError), + Status403(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`preview_flist_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum PreviewFlistHandlerError { + Status400(models::ResponseError), + Status401(models::ResponseError), + Status403(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`serve_flists`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ServeFlistsError { + Status404(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + + +pub async fn create_flist_handler(configuration: &configuration::Configuration, flist_body: models::FlistBody) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_flist_body = flist_body; + + let uri_str = format!("{}/api/v1/fl", configuration.base_path); + let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + if let Some(ref token) = configuration.bearer_access_token { + req_builder = req_builder.bearer_auth(token.to_owned()); + }; + req_builder = req_builder.json(&p_flist_body); + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Job`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Job`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +pub async fn get_flist_state_handler(configuration: &configuration::Configuration, job_id: &str) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_job_id = job_id; + + let uri_str = format!("{}/api/v1/fl/{job_id}", configuration.base_path, job_id=crate::apis::urlencode(p_job_id)); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + if let Some(ref token) = configuration.bearer_access_token { + req_builder = req_builder.bearer_auth(token.to_owned()); + }; + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::FlistStateResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::FlistStateResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +pub async fn list_flists_handler(configuration: &configuration::Configuration, ) -> Result>, Error> { + + let uri_str = format!("{}/api/v1/fl", configuration.base_path); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `std::collections::HashMap<String, Vec<models::FileInfo>>`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `std::collections::HashMap<String, Vec<models::FileInfo>>`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +pub async fn preview_flist_handler(configuration: &configuration::Configuration, flist_path: &str) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_flist_path = flist_path; + + let uri_str = format!("{}/api/v1/fl/preview/{flist_path}", configuration.base_path, flist_path=crate::apis::urlencode(p_flist_path)); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PreviewResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PreviewResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + +pub async fn serve_flists(configuration: &configuration::Configuration, path: &str) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_path = path; + + let uri_str = format!("{}/{path}", configuration.base_path, path=crate::apis::urlencode(p_path)); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + + if !status.is_client_error() && !status.is_server_error() { + Ok(resp) + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + diff --git a/rfs-client/openapi/src/apis/flist_serving_api.rs b/rfs-client/openapi/src/apis/flist_serving_api.rs new file mode 100644 index 0000000..a46204a --- /dev/null +++ b/rfs-client/openapi/src/apis/flist_serving_api.rs @@ -0,0 +1,63 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + + +use reqwest; +use serde::{Deserialize, Serialize, de::Error as _}; +use crate::{apis::ResponseContent, models}; +use super::{Error, configuration, ContentType}; + + +/// struct for typed errors of method [`serve_flists`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ServeFlistsError { + Status404(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + + +pub async fn serve_flists(configuration: &configuration::Configuration, path: &str) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_path = path; + + let uri_str = format!("{}/{path}", configuration.base_path, path=crate::apis::urlencode(p_path)); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ResponseResult`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ResponseResult`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + diff --git a/rfs-client/openapi/src/apis/mod.rs b/rfs-client/openapi/src/apis/mod.rs new file mode 100644 index 0000000..c713672 --- /dev/null +++ b/rfs-client/openapi/src/apis/mod.rs @@ -0,0 +1,121 @@ +use std::error; +use std::fmt; + +#[derive(Debug, Clone)] +pub struct ResponseContent { + pub status: reqwest::StatusCode, + pub content: String, + pub entity: Option, +} + +#[derive(Debug)] +pub enum Error { + Reqwest(reqwest::Error), + Serde(serde_json::Error), + Io(std::io::Error), + ResponseError(ResponseContent), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let (module, e) = match self { + Error::Reqwest(e) => ("reqwest", e.to_string()), + Error::Serde(e) => ("serde", e.to_string()), + Error::Io(e) => ("IO", e.to_string()), + Error::ResponseError(e) => ("response", format!("status code {}", e.status)), + }; + write!(f, "error in {}: {}", module, e) + } +} + +impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + Some(match self { + Error::Reqwest(e) => e, + Error::Serde(e) => e, + Error::Io(e) => e, + Error::ResponseError(_) => return None, + }) + } +} + +impl From for Error { + fn from(e: reqwest::Error) -> Self { + Error::Reqwest(e) + } +} + +impl From for Error { + fn from(e: serde_json::Error) -> Self { + Error::Serde(e) + } +} + +impl From for Error { + fn from(e: std::io::Error) -> Self { + Error::Io(e) + } +} + +pub fn urlencode>(s: T) -> String { + ::url::form_urlencoded::byte_serialize(s.as_ref().as_bytes()).collect() +} + +pub fn parse_deep_object(prefix: &str, value: &serde_json::Value) -> Vec<(String, String)> { + if let serde_json::Value::Object(object) = value { + let mut params = vec![]; + + for (key, value) in object { + match value { + serde_json::Value::Object(_) => params.append(&mut parse_deep_object( + &format!("{}[{}]", prefix, key), + value, + )), + serde_json::Value::Array(array) => { + for (i, value) in array.iter().enumerate() { + params.append(&mut parse_deep_object( + &format!("{}[{}][{}]", prefix, key, i), + value, + )); + } + }, + serde_json::Value::String(s) => params.push((format!("{}[{}]", prefix, key), s.clone())), + _ => params.push((format!("{}[{}]", prefix, key), value.to_string())), + } + } + + return params; + } + + unimplemented!("Only objects are supported with style=deepObject") +} + +/// Internal use only +/// A content type supported by this client. +#[allow(dead_code)] +enum ContentType { + Json, + Text, + Unsupported(String) +} + +impl From<&str> for ContentType { + fn from(content_type: &str) -> Self { + if content_type.starts_with("application") && content_type.contains("json") { + return Self::Json; + } else if content_type.starts_with("text/plain") { + return Self::Text; + } else { + return Self::Unsupported(content_type.to_string()); + } + } +} + +pub mod authentication_api; +pub mod block_management_api; +pub mod file_management_api; +pub mod flist_management_api; +pub mod system_api; +pub mod website_serving_api; + +pub mod configuration; diff --git a/rfs-client/openapi/src/apis/system_api.rs b/rfs-client/openapi/src/apis/system_api.rs new file mode 100644 index 0000000..d5fbe58 --- /dev/null +++ b/rfs-client/openapi/src/apis/system_api.rs @@ -0,0 +1,59 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + + +use reqwest; +use serde::{Deserialize, Serialize, de::Error as _}; +use crate::{apis::ResponseContent, models}; +use super::{Error, configuration, ContentType}; + + +/// struct for typed errors of method [`health_check_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum HealthCheckHandlerError { + UnknownValue(serde_json::Value), +} + + +pub async fn health_check_handler(configuration: &configuration::Configuration, ) -> Result> { + + let uri_str = format!("{}/api/v1", configuration.base_path); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); + + if !status.is_client_error() && !status.is_server_error() { + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::HealthResponse`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::HealthResponse`")))), + } + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + diff --git a/rfs-client/openapi/src/apis/website_serving_api.rs b/rfs-client/openapi/src/apis/website_serving_api.rs new file mode 100644 index 0000000..b9a3a3a --- /dev/null +++ b/rfs-client/openapi/src/apis/website_serving_api.rs @@ -0,0 +1,53 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + + +use reqwest; +use serde::{Deserialize, Serialize, de::Error as _}; +use crate::{apis::ResponseContent, models}; +use super::{Error, configuration, ContentType}; + + +/// struct for typed errors of method [`serve_website_handler`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ServeWebsiteHandlerError { + Status404(models::ResponseError), + Status500(models::ResponseError), + UnknownValue(serde_json::Value), +} + + +pub async fn serve_website_handler(configuration: &configuration::Configuration, website_hash: &str, path: &str) -> Result> { + // add a prefix to parameters to efficiently prevent name collisions + let p_website_hash = website_hash; + let p_path = path; + + let uri_str = format!("{}/api/v1/website/{website_hash}/{path}", configuration.base_path, website_hash=crate::apis::urlencode(p_website_hash), path=crate::apis::urlencode(p_path)); + let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str); + + if let Some(ref user_agent) = configuration.user_agent { + req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone()); + } + + let req = req_builder.build()?; + let resp = configuration.client.execute(req).await?; + + let status = resp.status(); + + if !status.is_client_error() && !status.is_server_error() { + Ok(resp) + } else { + let content = resp.text().await?; + let entity: Option = serde_json::from_str(&content).ok(); + Err(Error::ResponseError(ResponseContent { status, content, entity })) + } +} + diff --git a/rfs-client/openapi/src/lib.rs b/rfs-client/openapi/src/lib.rs new file mode 100644 index 0000000..e152062 --- /dev/null +++ b/rfs-client/openapi/src/lib.rs @@ -0,0 +1,11 @@ +#![allow(unused_imports)] +#![allow(clippy::too_many_arguments)] + +extern crate serde_repr; +extern crate serde; +extern crate serde_json; +extern crate url; +extern crate reqwest; + +pub mod apis; +pub mod models; diff --git a/rfs-client/openapi/src/models/block.rs b/rfs-client/openapi/src/models/block.rs new file mode 100644 index 0000000..40b4dcb --- /dev/null +++ b/rfs-client/openapi/src/models/block.rs @@ -0,0 +1,36 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct Block { + #[serde(rename = "data")] + pub data: std::path::PathBuf, + #[serde(rename = "hash")] + pub hash: String, + #[serde(rename = "index")] + pub index: i64, + #[serde(rename = "size")] + pub size: i32, +} + +impl Block { + pub fn new(data: std::path::PathBuf, hash: String, index: i64, size: i32) -> Block { + Block { + data, + hash, + index, + size, + } + } +} + diff --git a/rfs-client/openapi/src/models/block_downloads_response.rs b/rfs-client/openapi/src/models/block_downloads_response.rs new file mode 100644 index 0000000..5778e91 --- /dev/null +++ b/rfs-client/openapi/src/models/block_downloads_response.rs @@ -0,0 +1,38 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +/// BlockDownloadsResponse : Response for block downloads endpoint +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct BlockDownloadsResponse { + /// Block hash + #[serde(rename = "block_hash")] + pub block_hash: String, + /// Size of the block in bytes + #[serde(rename = "block_size")] + pub block_size: i64, + /// Number of times the block has been downloaded + #[serde(rename = "downloads_count")] + pub downloads_count: i64, +} + +impl BlockDownloadsResponse { + /// Response for block downloads endpoint + pub fn new(block_hash: String, block_size: i64, downloads_count: i64) -> BlockDownloadsResponse { + BlockDownloadsResponse { + block_hash, + block_size, + downloads_count, + } + } +} + diff --git a/rfs-client/openapi/src/models/block_info.rs b/rfs-client/openapi/src/models/block_info.rs new file mode 100644 index 0000000..bf9f653 --- /dev/null +++ b/rfs-client/openapi/src/models/block_info.rs @@ -0,0 +1,34 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +/// BlockInfo : Block information with hash and index +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct BlockInfo { + /// Block hash + #[serde(rename = "hash")] + pub hash: String, + /// Block index within the file + #[serde(rename = "index")] + pub index: i64, +} + +impl BlockInfo { + /// Block information with hash and index + pub fn new(hash: String, index: i64) -> BlockInfo { + BlockInfo { + hash, + index, + } + } +} + diff --git a/rfs-client/openapi/src/models/block_uploaded_response.rs b/rfs-client/openapi/src/models/block_uploaded_response.rs new file mode 100644 index 0000000..42dcf29 --- /dev/null +++ b/rfs-client/openapi/src/models/block_uploaded_response.rs @@ -0,0 +1,30 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct BlockUploadedResponse { + #[serde(rename = "hash")] + pub hash: String, + #[serde(rename = "message")] + pub message: String, +} + +impl BlockUploadedResponse { + pub fn new(hash: String, message: String) -> BlockUploadedResponse { + BlockUploadedResponse { + hash, + message, + } + } +} + diff --git a/rfs-client/openapi/src/models/blocks_response.rs b/rfs-client/openapi/src/models/blocks_response.rs new file mode 100644 index 0000000..cf2ed03 --- /dev/null +++ b/rfs-client/openapi/src/models/blocks_response.rs @@ -0,0 +1,30 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +/// BlocksResponse : Response for blocks by hash endpoint +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct BlocksResponse { + /// List of blocks with their indices + #[serde(rename = "blocks")] + pub blocks: Vec, +} + +impl BlocksResponse { + /// Response for blocks by hash endpoint + pub fn new(blocks: Vec) -> BlocksResponse { + BlocksResponse { + blocks, + } + } +} + diff --git a/rfs-client/openapi/src/models/dir_list_template.rs b/rfs-client/openapi/src/models/dir_list_template.rs new file mode 100644 index 0000000..f715f7e --- /dev/null +++ b/rfs-client/openapi/src/models/dir_list_template.rs @@ -0,0 +1,30 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct DirListTemplate { + #[serde(rename = "cur_path")] + pub cur_path: String, + #[serde(rename = "lister")] + pub lister: Box, +} + +impl DirListTemplate { + pub fn new(cur_path: String, lister: models::DirLister) -> DirListTemplate { + DirListTemplate { + cur_path, + lister: Box::new(lister), + } + } +} + diff --git a/rfs-client/openapi/src/models/dir_lister.rs b/rfs-client/openapi/src/models/dir_lister.rs new file mode 100644 index 0000000..e298cb9 --- /dev/null +++ b/rfs-client/openapi/src/models/dir_lister.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct DirLister { + #[serde(rename = "files")] + pub files: Vec, +} + +impl DirLister { + pub fn new(files: Vec) -> DirLister { + DirLister { + files, + } + } +} + diff --git a/rfs-client/openapi/src/models/error_template.rs b/rfs-client/openapi/src/models/error_template.rs new file mode 100644 index 0000000..65078ab --- /dev/null +++ b/rfs-client/openapi/src/models/error_template.rs @@ -0,0 +1,33 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ErrorTemplate { + #[serde(rename = "cur_path")] + pub cur_path: String, + #[serde(rename = "err")] + pub err: Box, + #[serde(rename = "message")] + pub message: String, +} + +impl ErrorTemplate { + pub fn new(cur_path: String, err: models::TemplateErr, message: String) -> ErrorTemplate { + ErrorTemplate { + cur_path, + err: Box::new(err), + message, + } + } +} + diff --git a/rfs-client/openapi/src/models/file.rs b/rfs-client/openapi/src/models/file.rs new file mode 100644 index 0000000..bc5195b --- /dev/null +++ b/rfs-client/openapi/src/models/file.rs @@ -0,0 +1,30 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct File { + #[serde(rename = "file_content")] + pub file_content: std::path::PathBuf, + #[serde(rename = "file_hash")] + pub file_hash: String, +} + +impl File { + pub fn new(file_content: std::path::PathBuf, file_hash: String) -> File { + File { + file_content, + file_hash, + } + } +} + diff --git a/rfs-client/openapi/src/models/file_download_request.rs b/rfs-client/openapi/src/models/file_download_request.rs new file mode 100644 index 0000000..dda3126 --- /dev/null +++ b/rfs-client/openapi/src/models/file_download_request.rs @@ -0,0 +1,30 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +/// FileDownloadRequest : Request for file download with custom filename +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct FileDownloadRequest { + /// The custom filename to use for download + #[serde(rename = "file_name")] + pub file_name: String, +} + +impl FileDownloadRequest { + /// Request for file download with custom filename + pub fn new(file_name: String) -> FileDownloadRequest { + FileDownloadRequest { + file_name, + } + } +} + diff --git a/rfs-client/openapi/src/models/file_info.rs b/rfs-client/openapi/src/models/file_info.rs new file mode 100644 index 0000000..8b1167c --- /dev/null +++ b/rfs-client/openapi/src/models/file_info.rs @@ -0,0 +1,42 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct FileInfo { + #[serde(rename = "is_file")] + pub is_file: bool, + #[serde(rename = "last_modified")] + pub last_modified: i64, + #[serde(rename = "name")] + pub name: String, + #[serde(rename = "path_uri")] + pub path_uri: String, + #[serde(rename = "progress")] + pub progress: f32, + #[serde(rename = "size")] + pub size: i64, +} + +impl FileInfo { + pub fn new(is_file: bool, last_modified: i64, name: String, path_uri: String, progress: f32, size: i64) -> FileInfo { + FileInfo { + is_file, + last_modified, + name, + path_uri, + progress, + size, + } + } +} + diff --git a/rfs-client/openapi/src/models/file_upload_response.rs b/rfs-client/openapi/src/models/file_upload_response.rs new file mode 100644 index 0000000..374cac0 --- /dev/null +++ b/rfs-client/openapi/src/models/file_upload_response.rs @@ -0,0 +1,34 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +/// FileUploadResponse : Response for file upload +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct FileUploadResponse { + /// The file hash + #[serde(rename = "file_hash")] + pub file_hash: String, + /// Message indicating success + #[serde(rename = "message")] + pub message: String, +} + +impl FileUploadResponse { + /// Response for file upload + pub fn new(file_hash: String, message: String) -> FileUploadResponse { + FileUploadResponse { + file_hash, + message, + } + } +} + diff --git a/rfs-client/openapi/src/models/flist_body.rs b/rfs-client/openapi/src/models/flist_body.rs new file mode 100644 index 0000000..ebea1e5 --- /dev/null +++ b/rfs-client/openapi/src/models/flist_body.rs @@ -0,0 +1,48 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct FlistBody { + #[serde(rename = "auth", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub auth: Option>, + #[serde(rename = "email", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub email: Option>, + #[serde(rename = "identity_token", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub identity_token: Option>, + #[serde(rename = "image_name")] + pub image_name: String, + #[serde(rename = "password", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub password: Option>, + #[serde(rename = "registry_token", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub registry_token: Option>, + #[serde(rename = "server_address", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub server_address: Option>, + #[serde(rename = "username", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub username: Option>, +} + +impl FlistBody { + pub fn new(image_name: String) -> FlistBody { + FlistBody { + auth: None, + email: None, + identity_token: None, + image_name, + password: None, + registry_token: None, + server_address: None, + username: None, + } + } +} + diff --git a/rfs-client/openapi/src/models/flist_state.rs b/rfs-client/openapi/src/models/flist_state.rs new file mode 100644 index 0000000..01411ea --- /dev/null +++ b/rfs-client/openapi/src/models/flist_state.rs @@ -0,0 +1,29 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum FlistState { + FlistStateAccepted(Box), + FlistStateStarted(Box), + FlistStateInProgress(Box), + FlistStateCreated(Box), + FlistStateFailed(String), +} + +impl Default for FlistState { + fn default() -> Self { + Self::FlistStateAccepted(Default::default()) + } +} + diff --git a/rfs-client/openapi/src/models/flist_state_accepted.rs b/rfs-client/openapi/src/models/flist_state_accepted.rs new file mode 100644 index 0000000..e2ac5a6 --- /dev/null +++ b/rfs-client/openapi/src/models/flist_state_accepted.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct FlistStateAccepted { + #[serde(rename = "Accepted")] + pub accepted: String, +} + +impl FlistStateAccepted { + pub fn new(accepted: String) -> FlistStateAccepted { + FlistStateAccepted { + accepted, + } + } +} + diff --git a/rfs-client/openapi/src/models/flist_state_created.rs b/rfs-client/openapi/src/models/flist_state_created.rs new file mode 100644 index 0000000..53a30fc --- /dev/null +++ b/rfs-client/openapi/src/models/flist_state_created.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct FlistStateCreated { + #[serde(rename = "Created")] + pub created: String, +} + +impl FlistStateCreated { + pub fn new(created: String) -> FlistStateCreated { + FlistStateCreated { + created, + } + } +} + diff --git a/rfs-client/openapi/src/models/flist_state_in_progress.rs b/rfs-client/openapi/src/models/flist_state_in_progress.rs new file mode 100644 index 0000000..9ed9069 --- /dev/null +++ b/rfs-client/openapi/src/models/flist_state_in_progress.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct FlistStateInProgress { + #[serde(rename = "InProgress")] + pub in_progress: Box, +} + +impl FlistStateInProgress { + pub fn new(in_progress: models::FlistStateInfo) -> FlistStateInProgress { + FlistStateInProgress { + in_progress: Box::new(in_progress), + } + } +} + diff --git a/rfs-client/openapi/src/models/flist_state_info.rs b/rfs-client/openapi/src/models/flist_state_info.rs new file mode 100644 index 0000000..dbf2d2f --- /dev/null +++ b/rfs-client/openapi/src/models/flist_state_info.rs @@ -0,0 +1,30 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct FlistStateInfo { + #[serde(rename = "msg")] + pub msg: String, + #[serde(rename = "progress")] + pub progress: f32, +} + +impl FlistStateInfo { + pub fn new(msg: String, progress: f32) -> FlistStateInfo { + FlistStateInfo { + msg, + progress, + } + } +} + diff --git a/rfs-client/openapi/src/models/flist_state_response.rs b/rfs-client/openapi/src/models/flist_state_response.rs new file mode 100644 index 0000000..9663aaa --- /dev/null +++ b/rfs-client/openapi/src/models/flist_state_response.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct FlistStateResponse { + #[serde(rename = "flist_state")] + pub flist_state: Box, +} + +impl FlistStateResponse { + pub fn new(flist_state: models::FlistState) -> FlistStateResponse { + FlistStateResponse { + flist_state: Box::new(flist_state), + } + } +} + diff --git a/rfs-client/openapi/src/models/flist_state_started.rs b/rfs-client/openapi/src/models/flist_state_started.rs new file mode 100644 index 0000000..ece9b7b --- /dev/null +++ b/rfs-client/openapi/src/models/flist_state_started.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct FlistStateStarted { + #[serde(rename = "Started")] + pub started: String, +} + +impl FlistStateStarted { + pub fn new(started: String) -> FlistStateStarted { + FlistStateStarted { + started, + } + } +} + diff --git a/rfs-client/openapi/src/models/health_response.rs b/rfs-client/openapi/src/models/health_response.rs new file mode 100644 index 0000000..47bab2f --- /dev/null +++ b/rfs-client/openapi/src/models/health_response.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct HealthResponse { + #[serde(rename = "msg")] + pub msg: String, +} + +impl HealthResponse { + pub fn new(msg: String) -> HealthResponse { + HealthResponse { + msg, + } + } +} + diff --git a/rfs-client/openapi/src/models/job.rs b/rfs-client/openapi/src/models/job.rs new file mode 100644 index 0000000..23ad5ff --- /dev/null +++ b/rfs-client/openapi/src/models/job.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct Job { + #[serde(rename = "id")] + pub id: String, +} + +impl Job { + pub fn new(id: String) -> Job { + Job { + id, + } + } +} + diff --git a/rfs-client/openapi/src/models/list_blocks_params.rs b/rfs-client/openapi/src/models/list_blocks_params.rs new file mode 100644 index 0000000..48e599d --- /dev/null +++ b/rfs-client/openapi/src/models/list_blocks_params.rs @@ -0,0 +1,34 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +/// ListBlocksParams : Query parameters for listing blocks +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ListBlocksParams { + /// Page number (1-indexed) + #[serde(rename = "page", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub page: Option>, + /// Number of items per page + #[serde(rename = "per_page", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")] + pub per_page: Option>, +} + +impl ListBlocksParams { + /// Query parameters for listing blocks + pub fn new() -> ListBlocksParams { + ListBlocksParams { + page: None, + per_page: None, + } + } +} + diff --git a/rfs-client/openapi/src/models/list_blocks_response.rs b/rfs-client/openapi/src/models/list_blocks_response.rs new file mode 100644 index 0000000..2921631 --- /dev/null +++ b/rfs-client/openapi/src/models/list_blocks_response.rs @@ -0,0 +1,42 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +/// ListBlocksResponse : Response for listing blocks +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ListBlocksResponse { + /// List of block hashes + #[serde(rename = "blocks")] + pub blocks: Vec, + /// Current page number + #[serde(rename = "page")] + pub page: i32, + /// Number of items per page + #[serde(rename = "per_page")] + pub per_page: i32, + /// Total number of blocks + #[serde(rename = "total")] + pub total: i64, +} + +impl ListBlocksResponse { + /// Response for listing blocks + pub fn new(blocks: Vec, page: i32, per_page: i32, total: i64) -> ListBlocksResponse { + ListBlocksResponse { + blocks, + page, + per_page, + total, + } + } +} + diff --git a/rfs-client/openapi/src/models/mod.rs b/rfs-client/openapi/src/models/mod.rs new file mode 100644 index 0000000..b82e6e7 --- /dev/null +++ b/rfs-client/openapi/src/models/mod.rs @@ -0,0 +1,102 @@ +pub mod block_downloads_response; +pub use self::block_downloads_response::BlockDownloadsResponse; +pub mod block_info; +pub use self::block_info::BlockInfo; +pub mod block_uploaded_response; +pub use self::block_uploaded_response::BlockUploadedResponse; +pub mod blocks_response; +pub use self::blocks_response::BlocksResponse; +pub mod dir_list_template; +pub use self::dir_list_template::DirListTemplate; +pub mod dir_lister; +pub use self::dir_lister::DirLister; +pub mod error_template; +pub use self::error_template::ErrorTemplate; +pub mod file_download_request; +pub use self::file_download_request::FileDownloadRequest; +pub mod file_info; +pub use self::file_info::FileInfo; +pub mod file_upload_response; +pub use self::file_upload_response::FileUploadResponse; +pub mod flist_body; +pub use self::flist_body::FlistBody; +pub mod flist_state; +pub use self::flist_state::FlistState; +pub mod flist_state_accepted; +pub use self::flist_state_accepted::FlistStateAccepted; +pub mod flist_state_created; +pub use self::flist_state_created::FlistStateCreated; +pub mod flist_state_in_progress; +pub use self::flist_state_in_progress::FlistStateInProgress; +pub mod flist_state_info; +pub use self::flist_state_info::FlistStateInfo; +pub mod flist_state_response; +pub use self::flist_state_response::FlistStateResponse; +pub mod flist_state_started; +pub use self::flist_state_started::FlistStateStarted; +pub mod health_response; +pub use self::health_response::HealthResponse; +pub mod job; +pub use self::job::Job; +pub mod list_blocks_params; +pub use self::list_blocks_params::ListBlocksParams; +pub mod list_blocks_response; +pub use self::list_blocks_response::ListBlocksResponse; +pub mod preview_response; +pub use self::preview_response::PreviewResponse; +pub mod response_error; +pub use self::response_error::ResponseError; +pub mod response_error_bad_request; +pub use self::response_error_bad_request::ResponseErrorBadRequest; +pub mod response_error_conflict; +pub use self::response_error_conflict::ResponseErrorConflict; +pub mod response_error_forbidden; +pub use self::response_error_forbidden::ResponseErrorForbidden; +pub mod response_error_not_found; +pub use self::response_error_not_found::ResponseErrorNotFound; +pub mod response_error_template_error; +pub use self::response_error_template_error::ResponseErrorTemplateError; +pub mod response_error_unauthorized; +pub use self::response_error_unauthorized::ResponseErrorUnauthorized; +pub mod response_result; +pub use self::response_result::ResponseResult; +pub mod response_result_block_uploaded; +pub use self::response_result_block_uploaded::ResponseResultBlockUploaded; +pub mod response_result_dir_template; +pub use self::response_result_dir_template::ResponseResultDirTemplate; +pub mod response_result_file_uploaded; +pub use self::response_result_file_uploaded::ResponseResultFileUploaded; +pub mod response_result_flist_created; +pub use self::response_result_flist_created::ResponseResultFlistCreated; +pub mod response_result_flist_state; +pub use self::response_result_flist_state::ResponseResultFlistState; +pub mod response_result_flists; +pub use self::response_result_flists::ResponseResultFlists; +pub mod response_result_preview_flist; +pub use self::response_result_preview_flist::ResponseResultPreviewFlist; +pub mod response_result_res; +pub use self::response_result_res::ResponseResultRes; +pub mod response_result_signed_in; +pub use self::response_result_signed_in::ResponseResultSignedIn; +pub mod sign_in_body; +pub use self::sign_in_body::SignInBody; +pub mod sign_in_response; +pub use self::sign_in_response::SignInResponse; +pub mod template_err; +pub use self::template_err::TemplateErr; +pub mod template_err_bad_request; +pub use self::template_err_bad_request::TemplateErrBadRequest; +pub mod template_err_internal_server_error; +pub use self::template_err_internal_server_error::TemplateErrInternalServerError; +pub mod template_err_not_found; +pub use self::template_err_not_found::TemplateErrNotFound; +pub mod upload_block_params; +pub use self::upload_block_params::UploadBlockParams; +pub mod user_blocks_response; +pub use self::user_blocks_response::UserBlocksResponse; +pub mod verify_block; +pub use self::verify_block::VerifyBlock; +pub mod verify_blocks_request; +pub use self::verify_blocks_request::VerifyBlocksRequest; +pub mod verify_blocks_response; +pub use self::verify_blocks_response::VerifyBlocksResponse; diff --git a/rfs-client/openapi/src/models/preview_response.rs b/rfs-client/openapi/src/models/preview_response.rs new file mode 100644 index 0000000..5197344 --- /dev/null +++ b/rfs-client/openapi/src/models/preview_response.rs @@ -0,0 +1,33 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct PreviewResponse { + #[serde(rename = "checksum")] + pub checksum: String, + #[serde(rename = "content")] + pub content: Vec, + #[serde(rename = "metadata")] + pub metadata: String, +} + +impl PreviewResponse { + pub fn new(checksum: String, content: Vec, metadata: String) -> PreviewResponse { + PreviewResponse { + checksum, + content, + metadata, + } + } +} + diff --git a/rfs-client/openapi/src/models/response_error.rs b/rfs-client/openapi/src/models/response_error.rs new file mode 100644 index 0000000..375c1e1 --- /dev/null +++ b/rfs-client/openapi/src/models/response_error.rs @@ -0,0 +1,31 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ResponseError { + ResponseErrorInternalServerError(String), + ResponseErrorConflict(Box), + ResponseErrorNotFound(Box), + ResponseErrorUnauthorized(Box), + ResponseErrorBadRequest(Box), + ResponseErrorForbidden(Box), + ResponseErrorTemplateError(Box), +} + +impl Default for ResponseError { + fn default() -> Self { + Self::ResponseErrorInternalServerError(Default::default()) + } +} + diff --git a/rfs-client/openapi/src/models/response_error_bad_request.rs b/rfs-client/openapi/src/models/response_error_bad_request.rs new file mode 100644 index 0000000..6bee067 --- /dev/null +++ b/rfs-client/openapi/src/models/response_error_bad_request.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseErrorBadRequest { + #[serde(rename = "BadRequest")] + pub bad_request: String, +} + +impl ResponseErrorBadRequest { + pub fn new(bad_request: String) -> ResponseErrorBadRequest { + ResponseErrorBadRequest { + bad_request, + } + } +} + diff --git a/rfs-client/openapi/src/models/response_error_conflict.rs b/rfs-client/openapi/src/models/response_error_conflict.rs new file mode 100644 index 0000000..fe2a5ce --- /dev/null +++ b/rfs-client/openapi/src/models/response_error_conflict.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseErrorConflict { + #[serde(rename = "Conflict")] + pub conflict: String, +} + +impl ResponseErrorConflict { + pub fn new(conflict: String) -> ResponseErrorConflict { + ResponseErrorConflict { + conflict, + } + } +} + diff --git a/rfs-client/openapi/src/models/response_error_forbidden.rs b/rfs-client/openapi/src/models/response_error_forbidden.rs new file mode 100644 index 0000000..a6e5324 --- /dev/null +++ b/rfs-client/openapi/src/models/response_error_forbidden.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseErrorForbidden { + #[serde(rename = "Forbidden")] + pub forbidden: String, +} + +impl ResponseErrorForbidden { + pub fn new(forbidden: String) -> ResponseErrorForbidden { + ResponseErrorForbidden { + forbidden, + } + } +} + diff --git a/rfs-client/openapi/src/models/response_error_not_found.rs b/rfs-client/openapi/src/models/response_error_not_found.rs new file mode 100644 index 0000000..6d0fd7b --- /dev/null +++ b/rfs-client/openapi/src/models/response_error_not_found.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseErrorNotFound { + #[serde(rename = "NotFound")] + pub not_found: String, +} + +impl ResponseErrorNotFound { + pub fn new(not_found: String) -> ResponseErrorNotFound { + ResponseErrorNotFound { + not_found, + } + } +} + diff --git a/rfs-client/openapi/src/models/response_error_template_error.rs b/rfs-client/openapi/src/models/response_error_template_error.rs new file mode 100644 index 0000000..265a08a --- /dev/null +++ b/rfs-client/openapi/src/models/response_error_template_error.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseErrorTemplateError { + #[serde(rename = "TemplateError")] + pub template_error: Box, +} + +impl ResponseErrorTemplateError { + pub fn new(template_error: models::ErrorTemplate) -> ResponseErrorTemplateError { + ResponseErrorTemplateError { + template_error: Box::new(template_error), + } + } +} + diff --git a/rfs-client/openapi/src/models/response_error_unauthorized.rs b/rfs-client/openapi/src/models/response_error_unauthorized.rs new file mode 100644 index 0000000..8ccbf63 --- /dev/null +++ b/rfs-client/openapi/src/models/response_error_unauthorized.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseErrorUnauthorized { + #[serde(rename = "Unauthorized")] + pub unauthorized: String, +} + +impl ResponseErrorUnauthorized { + pub fn new(unauthorized: String) -> ResponseErrorUnauthorized { + ResponseErrorUnauthorized { + unauthorized, + } + } +} + diff --git a/rfs-client/openapi/src/models/response_result.rs b/rfs-client/openapi/src/models/response_result.rs new file mode 100644 index 0000000..4200d44 --- /dev/null +++ b/rfs-client/openapi/src/models/response_result.rs @@ -0,0 +1,34 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ResponseResult { + ResponseResultHealth(String), + ResponseResultFlistCreated(Box), + ResponseResultFlistState(Box), + ResponseResultFlists(Box), + ResponseResultPreviewFlist(Box), + ResponseResultSignedIn(Box), + ResponseResultDirTemplate(Box), + ResponseResultBlockUploaded(Box), + ResponseResultFileUploaded(Box), + ResponseResultRes(Box), +} + +impl Default for ResponseResult { + fn default() -> Self { + Self::ResponseResultHealth(Default::default()) + } +} + diff --git a/rfs-client/openapi/src/models/response_result_block_uploaded.rs b/rfs-client/openapi/src/models/response_result_block_uploaded.rs new file mode 100644 index 0000000..9654b4a --- /dev/null +++ b/rfs-client/openapi/src/models/response_result_block_uploaded.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseResultBlockUploaded { + #[serde(rename = "BlockUploaded")] + pub block_uploaded: String, +} + +impl ResponseResultBlockUploaded { + pub fn new(block_uploaded: String) -> ResponseResultBlockUploaded { + ResponseResultBlockUploaded { + block_uploaded, + } + } +} + diff --git a/rfs-client/openapi/src/models/response_result_dir_template.rs b/rfs-client/openapi/src/models/response_result_dir_template.rs new file mode 100644 index 0000000..6963e6c --- /dev/null +++ b/rfs-client/openapi/src/models/response_result_dir_template.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseResultDirTemplate { + #[serde(rename = "DirTemplate")] + pub dir_template: Box, +} + +impl ResponseResultDirTemplate { + pub fn new(dir_template: models::DirListTemplate) -> ResponseResultDirTemplate { + ResponseResultDirTemplate { + dir_template: Box::new(dir_template), + } + } +} + diff --git a/rfs-client/openapi/src/models/response_result_file_uploaded.rs b/rfs-client/openapi/src/models/response_result_file_uploaded.rs new file mode 100644 index 0000000..0cc0fa1 --- /dev/null +++ b/rfs-client/openapi/src/models/response_result_file_uploaded.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseResultFileUploaded { + #[serde(rename = "FileUploaded")] + pub file_uploaded: Box, +} + +impl ResponseResultFileUploaded { + pub fn new(file_uploaded: models::FileUploadResponse) -> ResponseResultFileUploaded { + ResponseResultFileUploaded { + file_uploaded: Box::new(file_uploaded), + } + } +} + diff --git a/rfs-client/openapi/src/models/response_result_flist_created.rs b/rfs-client/openapi/src/models/response_result_flist_created.rs new file mode 100644 index 0000000..1742634 --- /dev/null +++ b/rfs-client/openapi/src/models/response_result_flist_created.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseResultFlistCreated { + #[serde(rename = "FlistCreated")] + pub flist_created: Box, +} + +impl ResponseResultFlistCreated { + pub fn new(flist_created: models::Job) -> ResponseResultFlistCreated { + ResponseResultFlistCreated { + flist_created: Box::new(flist_created), + } + } +} + diff --git a/rfs-client/openapi/src/models/response_result_flist_state.rs b/rfs-client/openapi/src/models/response_result_flist_state.rs new file mode 100644 index 0000000..9383526 --- /dev/null +++ b/rfs-client/openapi/src/models/response_result_flist_state.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseResultFlistState { + #[serde(rename = "FlistState")] + pub flist_state: Box, +} + +impl ResponseResultFlistState { + pub fn new(flist_state: models::FlistState) -> ResponseResultFlistState { + ResponseResultFlistState { + flist_state: Box::new(flist_state), + } + } +} + diff --git a/rfs-client/openapi/src/models/response_result_flists.rs b/rfs-client/openapi/src/models/response_result_flists.rs new file mode 100644 index 0000000..c86b8a7 --- /dev/null +++ b/rfs-client/openapi/src/models/response_result_flists.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseResultFlists { + #[serde(rename = "Flists")] + pub flists: std::collections::HashMap>, +} + +impl ResponseResultFlists { + pub fn new(flists: std::collections::HashMap>) -> ResponseResultFlists { + ResponseResultFlists { + flists, + } + } +} + diff --git a/rfs-client/openapi/src/models/response_result_preview_flist.rs b/rfs-client/openapi/src/models/response_result_preview_flist.rs new file mode 100644 index 0000000..70a11a4 --- /dev/null +++ b/rfs-client/openapi/src/models/response_result_preview_flist.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseResultPreviewFlist { + #[serde(rename = "PreviewFlist")] + pub preview_flist: Box, +} + +impl ResponseResultPreviewFlist { + pub fn new(preview_flist: models::PreviewResponse) -> ResponseResultPreviewFlist { + ResponseResultPreviewFlist { + preview_flist: Box::new(preview_flist), + } + } +} + diff --git a/rfs-client/openapi/src/models/response_result_res.rs b/rfs-client/openapi/src/models/response_result_res.rs new file mode 100644 index 0000000..5092a50 --- /dev/null +++ b/rfs-client/openapi/src/models/response_result_res.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseResultRes { + #[serde(rename = "Res")] + pub res: std::path::PathBuf, +} + +impl ResponseResultRes { + pub fn new(res: std::path::PathBuf) -> ResponseResultRes { + ResponseResultRes { + res, + } + } +} + diff --git a/rfs-client/openapi/src/models/response_result_signed_in.rs b/rfs-client/openapi/src/models/response_result_signed_in.rs new file mode 100644 index 0000000..6238750 --- /dev/null +++ b/rfs-client/openapi/src/models/response_result_signed_in.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct ResponseResultSignedIn { + #[serde(rename = "SignedIn")] + pub signed_in: Box, +} + +impl ResponseResultSignedIn { + pub fn new(signed_in: models::SignInResponse) -> ResponseResultSignedIn { + ResponseResultSignedIn { + signed_in: Box::new(signed_in), + } + } +} + diff --git a/rfs-client/openapi/src/models/sign_in_body.rs b/rfs-client/openapi/src/models/sign_in_body.rs new file mode 100644 index 0000000..83efdd0 --- /dev/null +++ b/rfs-client/openapi/src/models/sign_in_body.rs @@ -0,0 +1,30 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct SignInBody { + #[serde(rename = "password")] + pub password: String, + #[serde(rename = "username")] + pub username: String, +} + +impl SignInBody { + pub fn new(password: String, username: String) -> SignInBody { + SignInBody { + password, + username, + } + } +} + diff --git a/rfs-client/openapi/src/models/sign_in_response.rs b/rfs-client/openapi/src/models/sign_in_response.rs new file mode 100644 index 0000000..9604496 --- /dev/null +++ b/rfs-client/openapi/src/models/sign_in_response.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct SignInResponse { + #[serde(rename = "access_token")] + pub access_token: String, +} + +impl SignInResponse { + pub fn new(access_token: String) -> SignInResponse { + SignInResponse { + access_token, + } + } +} + diff --git a/rfs-client/openapi/src/models/template_err.rs b/rfs-client/openapi/src/models/template_err.rs new file mode 100644 index 0000000..8e16e46 --- /dev/null +++ b/rfs-client/openapi/src/models/template_err.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum TemplateErr { + TemplateErrBadRequest(Box), + TemplateErrNotFound(Box), + TemplateErrInternalServerError(Box), +} + +impl Default for TemplateErr { + fn default() -> Self { + Self::TemplateErrBadRequest(Default::default()) + } +} + diff --git a/rfs-client/openapi/src/models/template_err_bad_request.rs b/rfs-client/openapi/src/models/template_err_bad_request.rs new file mode 100644 index 0000000..c2d392e --- /dev/null +++ b/rfs-client/openapi/src/models/template_err_bad_request.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct TemplateErrBadRequest { + #[serde(rename = "BadRequest")] + pub bad_request: String, +} + +impl TemplateErrBadRequest { + pub fn new(bad_request: String) -> TemplateErrBadRequest { + TemplateErrBadRequest { + bad_request, + } + } +} + diff --git a/rfs-client/openapi/src/models/template_err_internal_server_error.rs b/rfs-client/openapi/src/models/template_err_internal_server_error.rs new file mode 100644 index 0000000..695216c --- /dev/null +++ b/rfs-client/openapi/src/models/template_err_internal_server_error.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct TemplateErrInternalServerError { + #[serde(rename = "InternalServerError")] + pub internal_server_error: String, +} + +impl TemplateErrInternalServerError { + pub fn new(internal_server_error: String) -> TemplateErrInternalServerError { + TemplateErrInternalServerError { + internal_server_error, + } + } +} + diff --git a/rfs-client/openapi/src/models/template_err_not_found.rs b/rfs-client/openapi/src/models/template_err_not_found.rs new file mode 100644 index 0000000..2f1929f --- /dev/null +++ b/rfs-client/openapi/src/models/template_err_not_found.rs @@ -0,0 +1,27 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct TemplateErrNotFound { + #[serde(rename = "NotFound")] + pub not_found: String, +} + +impl TemplateErrNotFound { + pub fn new(not_found: String) -> TemplateErrNotFound { + TemplateErrNotFound { + not_found, + } + } +} + diff --git a/rfs-client/openapi/src/models/upload_block_params.rs b/rfs-client/openapi/src/models/upload_block_params.rs new file mode 100644 index 0000000..73f5fb6 --- /dev/null +++ b/rfs-client/openapi/src/models/upload_block_params.rs @@ -0,0 +1,34 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +/// UploadBlockParams : Query parameters for uploading a block +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct UploadBlockParams { + /// File hash associated with the block + #[serde(rename = "file_hash")] + pub file_hash: String, + /// Block index within the file + #[serde(rename = "idx")] + pub idx: i64, +} + +impl UploadBlockParams { + /// Query parameters for uploading a block + pub fn new(file_hash: String, idx: i64) -> UploadBlockParams { + UploadBlockParams { + file_hash, + idx, + } + } +} + diff --git a/rfs-client/openapi/src/models/user_blocks_response.rs b/rfs-client/openapi/src/models/user_blocks_response.rs new file mode 100644 index 0000000..af871a5 --- /dev/null +++ b/rfs-client/openapi/src/models/user_blocks_response.rs @@ -0,0 +1,38 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +/// UserBlocksResponse : Response for user blocks endpoint +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct UserBlocksResponse { + /// Total number of all blocks + #[serde(rename = "all_blocks")] + pub all_blocks: i64, + /// List of blocks with their indices + #[serde(rename = "blocks")] + pub blocks: Vec, + /// Total number of blocks + #[serde(rename = "total")] + pub total: i64, +} + +impl UserBlocksResponse { + /// Response for user blocks endpoint + pub fn new(all_blocks: i64, blocks: Vec, total: i64) -> UserBlocksResponse { + UserBlocksResponse { + all_blocks, + blocks, + total, + } + } +} + diff --git a/rfs-client/openapi/src/models/verify_block.rs b/rfs-client/openapi/src/models/verify_block.rs new file mode 100644 index 0000000..a330b83 --- /dev/null +++ b/rfs-client/openapi/src/models/verify_block.rs @@ -0,0 +1,38 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +/// VerifyBlock : Request to verify if multiple blocks exist on the server +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct VerifyBlock { + /// Block hash to verify + #[serde(rename = "block_hash")] + pub block_hash: String, + /// Block index within the file + #[serde(rename = "block_index")] + pub block_index: i64, + /// File hash associated with the block + #[serde(rename = "file_hash")] + pub file_hash: String, +} + +impl VerifyBlock { + /// Request to verify if multiple blocks exist on the server + pub fn new(block_hash: String, block_index: i64, file_hash: String) -> VerifyBlock { + VerifyBlock { + block_hash, + block_index, + file_hash, + } + } +} + diff --git a/rfs-client/openapi/src/models/verify_blocks_request.rs b/rfs-client/openapi/src/models/verify_blocks_request.rs new file mode 100644 index 0000000..51a8fd3 --- /dev/null +++ b/rfs-client/openapi/src/models/verify_blocks_request.rs @@ -0,0 +1,28 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct VerifyBlocksRequest { + /// List of blocks to verify + #[serde(rename = "blocks")] + pub blocks: Vec, +} + +impl VerifyBlocksRequest { + pub fn new(blocks: Vec) -> VerifyBlocksRequest { + VerifyBlocksRequest { + blocks, + } + } +} + diff --git a/rfs-client/openapi/src/models/verify_blocks_response.rs b/rfs-client/openapi/src/models/verify_blocks_response.rs new file mode 100644 index 0000000..69065b1 --- /dev/null +++ b/rfs-client/openapi/src/models/verify_blocks_response.rs @@ -0,0 +1,30 @@ +/* + * rfs + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.2.0 + * + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +/// VerifyBlocksResponse : Response with list of missing blocks +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct VerifyBlocksResponse { + /// List of block hashes that are missing on the server + #[serde(rename = "missing")] + pub missing: Vec, +} + +impl VerifyBlocksResponse { + /// Response with list of missing blocks + pub fn new(missing: Vec) -> VerifyBlocksResponse { + VerifyBlocksResponse { + missing, + } + } +} + diff --git a/rfs-client/openapitools.json b/rfs-client/openapitools.json new file mode 100644 index 0000000..151c200 --- /dev/null +++ b/rfs-client/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "7.13.0" + } +} diff --git a/rfs-client/rust-toolchain.toml b/rfs-client/rust-toolchain.toml new file mode 100644 index 0000000..8b5d745 --- /dev/null +++ b/rfs-client/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "1.82.0" + diff --git a/rfs-client/src/client.rs b/rfs-client/src/client.rs new file mode 100644 index 0000000..f96d1af --- /dev/null +++ b/rfs-client/src/client.rs @@ -0,0 +1,429 @@ +use std::path::Path; +use std::sync::Arc; +use std::collections::HashMap; +use bytes::Bytes; + +use openapi::{ + apis::{ + authentication_api, block_management_api, flist_management_api, + file_management_api, system_api, website_serving_api, + configuration::Configuration, + Error as OpenApiError, + }, + models::{ + SignInBody, ListBlocksParams, + VerifyBlocksRequest, VerifyBlocksResponse, VerifyBlock, FlistBody, UserBlocksResponse, BlockDownloadsResponse, + BlocksResponse, PreviewResponse, FileInfo, FlistState, ResponseResult, FlistStateResponse, BlockUploadedResponse, FileUploadResponse, + }, +}; + +use crate::error::{RfsError, Result, map_openapi_error}; +use crate::types::{ClientConfig, UploadOptions, DownloadOptions, FlistOptions, WaitOptions}; + +/// Main client for interacting with the RFS server +#[derive(Clone)] +pub struct RfsClient { + config: Arc, + client_config: ClientConfig, + auth_token: Option, +} + +impl RfsClient { + /// Create a new RFS client with the given configuration + pub fn new(client_config: ClientConfig) -> Self { + // Create a custom reqwest client with timeout configuration + let client = reqwest::Client::builder() + .timeout(std::time::Duration::from_secs(client_config.timeout_seconds)) + .build() + .unwrap_or_default(); + + // Create OpenAPI configuration with our custom client + let mut config = Configuration::new(); + config.base_path = client_config.base_url.clone(); + config.user_agent = Some(format!("rfs-client/0.1.0")); + config.client = client; + + Self { + config: Arc::new(config), + client_config, + auth_token: None, + } + } + + /// Create a new RFS client with default configuration + pub fn default() -> Self { + Self::new(ClientConfig::default()) + } + + /// Authenticate with the RFS server + pub async fn authenticate(&mut self) -> Result<()> { + if let Some(credentials) = &self.client_config.credentials { + let sign_in_body = SignInBody { + username: credentials.username.clone(), + password: credentials.password.clone(), + }; + + let result = authentication_api::sign_in_handler(&self.config, sign_in_body) + .await + .map_err(map_openapi_error)?; + + if let Some(token) = Some(result.access_token) { + // Create a custom reqwest client with timeout configuration + let client = reqwest::Client::builder() + .timeout(std::time::Duration::from_secs(self.client_config.timeout_seconds)) + .build() + .unwrap_or_default(); + + // Create a new configuration with the auth token and timeout + let mut new_config = Configuration::new(); + new_config.base_path = self.client_config.base_url.clone(); + new_config.user_agent = Some(format!("rfs-client/0.1.0")); + new_config.bearer_access_token = Some(token.clone()); + new_config.client = client; + + self.config = Arc::new(new_config); + self.auth_token = Some(token); + Ok(()) + } else { + Err(RfsError::AuthError("No token received from server".to_string())) + } + } else { + Err(RfsError::AuthError("No credentials provided".to_string())) + } + } + + /// Check if the client is authenticated + pub fn is_authenticated(&self) -> bool { + self.auth_token.is_some() + } + + /// Get system information + pub async fn get_system_info(&self) -> Result { + let result = system_api::health_check_handler(&self.config) + .await + .map_err(map_openapi_error)?; + + Ok(result.msg) + } + + /// Upload a file to the RFS server + pub async fn upload_file>(&self, file_path: P, options: Option) -> Result { + let file_path = file_path.as_ref(); + let _options = options.unwrap_or_default(); + + // Check if file exists + if !file_path.exists() { + return Err(RfsError::FileSystemError(format!("File not found: {}", file_path.display()))); + } + + // Use the OpenAPI client to upload the file + let result = file_management_api::upload_file_handler(&self.config, file_path.to_path_buf()) + .await + .map_err(map_openapi_error)?; + + // Extract the file hash from the response + match result { + FileUploadResponse { file_hash, .. } => { + Ok(file_hash.clone()) + }, + _ => Err(RfsError::Other("Unexpected response type from file upload".to_string())), + } + } + + /// Download a file from the RFS server + pub async fn download_file>(&self, file_id: &str, output_path: P, options: Option) -> Result<()> { + let output_path = output_path.as_ref(); + let _options = options.unwrap_or_default(); + + // Create parent directories if needed + if let Some(parent) = output_path.parent() { + std::fs::create_dir_all(parent) + .map_err(|e| RfsError::FileSystemError(format!("Failed to create directory: {}", e)))?; + } + + // Create a FileDownloadRequest with the filename from the output path + let file_name = output_path.file_name() + .and_then(|n| n.to_str()) + .unwrap_or("downloaded_file") + .to_string(); + + let download_request = openapi::models::FileDownloadRequest::new(file_name); + + // Download the file + let response = file_management_api::get_file_handler(&self.config, file_id, download_request) + .await + .map_err(map_openapi_error)?; + + // Read the response body + let bytes = response.bytes() + .await + .map_err(|e| RfsError::RequestError(e))?; + + // Write the file to disk + std::fs::write(output_path, bytes) + .map_err(|e| RfsError::FileSystemError(format!("Failed to write file: {}", e)))?; + + Ok(()) + } + + /// List blocks with optional filtering + pub async fn list_blocks(&self, params: Option) -> Result> { + let page = params.as_ref().and_then(|p| p.page).flatten(); + let per_page = params.as_ref().and_then(|p| p.per_page).flatten(); + let result = block_management_api::list_blocks_handler(&self.config, page, per_page) + .await + .map_err(map_openapi_error)?; + + Ok(result.blocks) + } + + /// Verify blocks + pub async fn verify_blocks(&self, request: VerifyBlocksRequest) -> Result { + let result = block_management_api::verify_blocks_handler(&self.config, request) + .await + .map_err(map_openapi_error)?; + + Ok(result) + } + + /// Create a new FList from a Docker image + pub async fn create_flist(&self, image_name: &str, options: Option) -> Result { + // Ensure the client is authenticated + if !self.is_authenticated() { + return Err(RfsError::AuthError("Authentication required for creating FLists".to_string())); + } + + // Create FList body with the required fields + let mut flist = FlistBody::new(image_name.to_string()); + + // Apply options if provided + if let Some(opts) = options { + flist.username = opts.username.map(Some); + flist.password = opts.password.map(Some); + flist.auth = opts.auth.map(Some); + flist.email = opts.email.map(Some); + flist.server_address = opts.server_address.map(Some); + flist.identity_token = opts.identity_token.map(Some); + flist.registry_token = opts.registry_token.map(Some); + } + + // Call the API to create the FList + let result = flist_management_api::create_flist_handler(&self.config, flist) + .await + .map_err(map_openapi_error)?; + + // Return the job ID + Ok(result.id) + } + + /// Get FList state by job ID + pub async fn get_flist_state(&self, job_id: &str) -> Result { + // Ensure the client is authenticated + if !self.is_authenticated() { + return Err(RfsError::AuthError("Authentication required for accessing FList state".to_string())); + } + + // Call the API to get the FList state + let result = flist_management_api::get_flist_state_handler(&self.config, job_id) + .await + .map_err(map_openapi_error)?; + + Ok(result) + } + + /// Wait for an FList to be created + /// + /// This method polls the FList state until it reaches a terminal state (Created or Failed) + /// or until the timeout is reached. + pub async fn wait_for_flist_creation(&self, job_id: &str, options: Option) -> Result { + let options = options.unwrap_or_default(); + let deadline = std::time::Instant::now() + std::time::Duration::from_secs(options.timeout_seconds); + + loop { + // Check if we've exceeded the timeout + if std::time::Instant::now() > deadline { + return Err(RfsError::TimeoutError(format!( + "Timed out waiting for FList creation after {} seconds", + options.timeout_seconds + ))); + } + + // Get the current state + let state_result = self.get_flist_state(job_id).await; + + match state_result { + Ok(state) => { + // Call progress callback if provided + if let Some(ref callback) = options.progress_callback { + callback(state.flist_state.as_ref()); + } + + // Check if we've reached a terminal state + match state.flist_state.as_ref() { + FlistState::FlistStateCreated(_) => { + // Success! FList was created + return Ok(state); + }, + FlistState::FlistStateFailed(error_msg) => { + // Failure! FList creation failed + return Err(RfsError::FListError(format!("FList creation failed: {}", error_msg))); + }, + _ => { + // Still in progress, continue polling + tokio::time::sleep(std::time::Duration::from_millis(options.poll_interval_ms)).await; + } + } + }, + Err(e) => { + // If we get a 404 error, it might be because the FList job is still initializing + // Just wait and retry + println!("Warning: Error checking FList state: {}", e); + println!("Retrying in {} ms...", options.poll_interval_ms); + tokio::time::sleep(std::time::Duration::from_millis(options.poll_interval_ms)).await; + } + } + } + } + + /// Check if a block exists + pub async fn check_block(&self, hash: &str) -> Result { + match block_management_api::check_block_handler(&self.config, hash).await { + Ok(_) => Ok(true), + Err(OpenApiError::ResponseError(resp)) if resp.status.as_u16() == 404 => Ok(false), + Err(e) => Err(map_openapi_error(e)), + } + } + + /// Get block download statistics + pub async fn get_block_downloads(&self, hash: &str) -> Result { + let result = block_management_api::get_block_downloads_handler(&self.config, hash) + .await + .map_err(map_openapi_error)?; + + Ok(result) + } + + /// Download a specific block + pub async fn get_block(&self, hash: &str) -> Result { + let response = block_management_api::get_block_handler(&self.config, hash) + .await + .map_err(map_openapi_error)?; + + let bytes = response.bytes().await + .map_err(|e| RfsError::RequestError(e))?; + + Ok(bytes) + } + + /// Get blocks by hash (file hash or block hash) + pub async fn get_blocks_by_hash(&self, hash: &str) -> Result { + let result = block_management_api::get_blocks_by_hash_handler(&self.config, hash) + .await + .map_err(map_openapi_error)?; + + Ok(result) + } + + /// Get blocks uploaded by the current user + pub async fn get_user_blocks(&self, page: Option, per_page: Option) -> Result { + let result = block_management_api::get_user_blocks_handler(&self.config, page, per_page) + .await + .map_err(map_openapi_error)?; + + Ok(result) + } + + /// Upload a single block + pub async fn upload_block(&self, file_hash: &str, idx: i64, data: Vec) -> Result { + // Create a temporary file to hold the block data + let temp_dir = std::env::temp_dir(); + let temp_file_path = temp_dir.join(format!("{}-{}", file_hash, idx)); + + // Write the data to the temporary file + std::fs::write(&temp_file_path, &data) + .map_err(|e| RfsError::FileSystemError(format!("Failed to write temporary block file: {}", e)))?; + + // Upload the block + let result = block_management_api::upload_block_handler( + &self.config, + file_hash, + idx, + temp_file_path.clone(), + ) + .await + .map_err(map_openapi_error)?; + + // Clean up the temporary file + if let Err(e) = std::fs::remove_file(temp_file_path) { + eprintln!("Warning: Failed to remove temporary block file: {}", e); + } + + // Return the hash from the response + Ok(result.hash) + } + + /// List all FLists + pub async fn list_flists(&self) -> Result>> { + let result = flist_management_api::list_flists_handler(&self.config) + .await + .map_err(map_openapi_error)?; + + Ok(result) + } + + /// Preview an FList + pub async fn preview_flist(&self, flist_path: &str) -> Result { + let result = flist_management_api::preview_flist_handler(&self.config, flist_path) + .await + .map_err(map_openapi_error)?; + + Ok(result) + } + + /// Get website content + pub async fn get_website(&self, website_id: &str, path: &str) -> Result { + let result = website_serving_api::serve_website_handler(&self.config, website_id, path) + .await + .map_err(map_openapi_error)?; + + Ok(result) + } + + /// Health check + pub async fn health_check(&self) -> Result { + let result = system_api::health_check_handler(&self.config) + .await + .map_err(map_openapi_error)?; + + Ok(result.msg) + } + + + /// Download an FList file + /// + /// This method downloads an FList from the server and saves it to the specified path. + pub async fn download_flist>(&self, flist_path: &str, output_path: P) -> Result<()> { + let response = flist_management_api::serve_flists(&self.config, flist_path) + .await + .map_err(map_openapi_error)?; + + let bytes = response.bytes().await + .map_err(|e| RfsError::RequestError(e))?; + + std::fs::write(output_path, &bytes) + .map_err(|e| RfsError::FileSystemError(e.to_string()))?; + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_client_creation() { + let client = RfsClient::default(); + assert!(!client.is_authenticated()); + } +} diff --git a/rfs-client/src/error.rs b/rfs-client/src/error.rs new file mode 100644 index 0000000..09224e3 --- /dev/null +++ b/rfs-client/src/error.rs @@ -0,0 +1,53 @@ +use thiserror::Error; + +/// Errors that can occur when using the RFS client +#[derive(Error, Debug)] +pub enum RfsError { + /// Error from the underlying OpenAPI client + #[error("OpenAPI client error: {0}")] + OpenApiError(String), + + /// Error when making HTTP requests + #[error("HTTP request error: {0}")] + RequestError(#[from] reqwest::Error), + + /// Error when parsing URLs + #[error("URL parse error: {0}")] + UrlParseError(#[from] url::ParseError), + + /// Error when parsing JSON + #[error("JSON parse error: {0}")] + JsonError(#[from] serde_json::Error), + + /// Authentication error + #[error("Authentication error: {0}")] + AuthError(String), + + /// File system error + #[error("File system error: {0}")] + FileSystemError(String), + + /// Block management error + #[error("Block management error: {0}")] + BlockError(String), + + /// FList management error + #[error("FList management error: {0}")] + FListError(String), + + /// Timeout error + #[error("Operation timed out: {0}")] + TimeoutError(String), + + /// Generic error + #[error("{0}")] + Other(String), +} + +/// Result type for RFS client operations +pub type Result = std::result::Result; + +/// Convert OpenAPI errors to RfsError +pub(crate) fn map_openapi_error(err: E) -> RfsError { + RfsError::OpenApiError(err.to_string()) +} diff --git a/rfs-client/src/lib.rs b/rfs-client/src/lib.rs new file mode 100644 index 0000000..b9c0b52 --- /dev/null +++ b/rfs-client/src/lib.rs @@ -0,0 +1,12 @@ +// RFS Client - A client library for the Remote File System server +// This library wraps the OpenAPI-generated client to provide a more user-friendly interface + +pub mod client; +pub mod error; +pub mod types; + +pub use client::RfsClient; +pub use error::RfsError; + +// Re-export types from the OpenAPI client that are commonly used +pub use openapi::models; diff --git a/rfs-client/src/types.rs b/rfs-client/src/types.rs new file mode 100644 index 0000000..c249699 --- /dev/null +++ b/rfs-client/src/types.rs @@ -0,0 +1,115 @@ +// Re-export common types from OpenAPI client for convenience +pub use openapi::models::{ + BlockDownloadsResponse, BlocksResponse, FileInfo, + FileUploadResponse, FlistBody, FlistState, Job, ListBlocksResponse, + PreviewResponse, ResponseResult, SignInResponse, VerifyBlocksResponse, +}; + +/// Authentication credentials for the RFS server +#[derive(Clone, Debug)] +pub struct Credentials { + /// Username for authentication + pub username: String, + /// Password for authentication + pub password: String, +} + +/// Configuration for the RFS client +#[derive(Clone, Debug)] +pub struct ClientConfig { + /// Base URL of the RFS server + pub base_url: String, + /// Optional authentication credentials + pub credentials: Option, + /// Timeout for API requests in seconds + pub timeout_seconds: u64, +} + +impl Default for ClientConfig { + fn default() -> Self { + Self { + base_url: "http://localhost:8080".to_string(), + credentials: None, + timeout_seconds: 30, + } + } +} + +/// Upload options for file uploads +#[derive(Clone, Debug, Default)] +pub struct UploadOptions { + /// Chunk size for uploading large files + pub chunk_size: Option, + /// Whether to verify blocks after upload + pub verify: bool, +} + +/// Download options for file downloads +#[derive(Clone, Debug, Default)] +pub struct DownloadOptions { + /// Whether to verify blocks during download + pub verify: bool, +} + +/// Options for creating FLists +#[derive(Clone, Debug, Default)] +pub struct FlistOptions { + /// Optional username for registry authentication + pub username: Option, + /// Optional password for registry authentication + pub password: Option, + /// Optional auth token for registry authentication + pub auth: Option, + /// Optional email for registry authentication + pub email: Option, + /// Optional server address for registry + pub server_address: Option, + /// Optional identity token for registry authentication + pub identity_token: Option, + /// Optional registry token for registry authentication + pub registry_token: Option, +} + +/// Options for waiting operations +pub struct WaitOptions { + /// Maximum time to wait in seconds + pub timeout_seconds: u64, + + /// Polling interval in milliseconds + pub poll_interval_ms: u64, + + /// Optional progress callback + pub progress_callback: Option>, +} + +// Manual implementation of Debug for WaitOptions +impl std::fmt::Debug for WaitOptions { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("WaitOptions") + .field("timeout_seconds", &self.timeout_seconds) + .field("poll_interval_ms", &self.poll_interval_ms) + .field("progress_callback", &if self.progress_callback.is_some() { "Some(...)" } else { "None" }) + .finish() + } +} + +// Manual implementation of Clone for WaitOptions +impl Clone for WaitOptions { + fn clone(&self) -> Self { + Self { + timeout_seconds: self.timeout_seconds, + poll_interval_ms: self.poll_interval_ms, + progress_callback: None, // We can't clone the callback function + } + } +} + +impl Default for WaitOptions { + fn default() -> Self { + Self { + timeout_seconds: 300, // 5 minutes default timeout + poll_interval_ms: 1000, // 1 second default polling interval + progress_callback: None, + } + } +}