docs: Add Rustdoc comments to CompressionService methods
Co-authored-by: aider (openai/andrew/openrouter/sonoma-sky-alpha) <aider@aider.chat>
This commit is contained in:
@@ -71,6 +71,9 @@ pub struct FilterOption {
|
|||||||
pub trait FilterPlugin: Send {
|
pub trait FilterPlugin: Send {
|
||||||
/// Processes the input stream and writes the filtered output.
|
/// Processes the input stream and writes the filtered output.
|
||||||
///
|
///
|
||||||
|
/// This method reads from the input reader and applies filtering logic,
|
||||||
|
/// writing the processed data to the output writer.
|
||||||
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `reader` - A boxed mutable reference to the input reader providing the data to filter.
|
/// * `reader` - A boxed mutable reference to the input reader providing the data to filter.
|
||||||
@@ -79,18 +82,64 @@ pub trait FilterPlugin: Send {
|
|||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A `Result` indicating success (`Ok(())`) or failure with an `io::Error`.
|
/// A `Result` indicating success (`Ok(())`) or failure with an `io::Error`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// impl FilterPlugin for MyFilter {
|
||||||
|
/// fn filter(&mut self, reader: Box<&mut dyn Read>, writer: Box<&mut dyn Write>) -> Result<()> {
|
||||||
|
/// // Read and filter data
|
||||||
|
/// let mut buf = [0; 1024];
|
||||||
|
/// while let Ok(n) = reader.as_mut().read(&mut buf) {
|
||||||
|
/// if n == 0 { break; }
|
||||||
|
/// // Apply filter logic to buf[0..n]
|
||||||
|
/// writer.as_mut().write_all(&buf[0..n])?;
|
||||||
|
/// }
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// // ... other methods
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
fn filter(&mut self, reader: Box<&mut dyn Read>, writer: Box<&mut dyn Write>) -> Result<()>;
|
fn filter(&mut self, reader: Box<&mut dyn Read>, writer: Box<&mut dyn Write>) -> Result<()>;
|
||||||
|
|
||||||
/// Clones this plugin into a new boxed instance.
|
/// Clones this plugin into a new boxed instance.
|
||||||
///
|
///
|
||||||
|
/// This method is required for dynamic dispatch and cloning in filter chains.
|
||||||
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A new `Box<dyn FilterPlugin>` clone of the current plugin.
|
/// A new `Box<dyn FilterPlugin>` clone of the current plugin.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// fn clone_box(&self) -> Box<dyn FilterPlugin> {
|
||||||
|
/// Box::new(self.clone())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
fn clone_box(&self) -> Box<dyn FilterPlugin>;
|
fn clone_box(&self) -> Box<dyn FilterPlugin>;
|
||||||
|
|
||||||
/// Returns the configuration options for this plugin.
|
/// Returns the configuration options for this plugin.
|
||||||
///
|
///
|
||||||
|
/// Describes the configurable parameters, including names, defaults, and required flags.
|
||||||
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A vector of `FilterOption` structs describing the plugin's options.
|
/// A vector of `FilterOption` structs describing the plugin's options.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// fn options(&self) -> Vec<FilterOption> {
|
||||||
|
/// vec![
|
||||||
|
/// FilterOption {
|
||||||
|
/// name: "pattern".to_string(),
|
||||||
|
/// default: None,
|
||||||
|
/// required: true,
|
||||||
|
/// },
|
||||||
|
/// ]
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
fn options(&self) -> Vec<FilterOption>;
|
fn options(&self) -> Vec<FilterOption>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +176,22 @@ pub struct FilterChain {
|
|||||||
plugins: Vec<Box<dyn FilterPlugin>>,
|
plugins: Vec<Box<dyn FilterPlugin>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A chain of filter plugins applied sequentially.
|
||||||
|
///
|
||||||
|
/// Chains multiple filters, applying them in order to the input stream.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
///
|
||||||
|
/// * `plugins` - Vector of boxed filter plugins.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let mut chain = FilterChain::new();
|
||||||
|
/// chain.add_plugin(Box::new(HeadLinesFilter::new(10)));
|
||||||
|
/// chain.filter(&mut reader, &mut writer)?;
|
||||||
|
/// ```
|
||||||
|
|
||||||
impl Clone for FilterChain {
|
impl Clone for FilterChain {
|
||||||
/// Clones this filter chain.
|
/// Clones this filter chain.
|
||||||
///
|
///
|
||||||
@@ -159,6 +224,13 @@ impl FilterChain {
|
|||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A new `FilterChain` with no plugins.
|
/// A new `FilterChain` with no plugins.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let chain = FilterChain::new();
|
||||||
|
/// assert!(chain.plugins.is_empty());
|
||||||
|
/// ```
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
plugins: Vec::new(),
|
plugins: Vec::new(),
|
||||||
@@ -167,15 +239,27 @@ impl FilterChain {
|
|||||||
|
|
||||||
/// Adds a plugin to the chain.
|
/// Adds a plugin to the chain.
|
||||||
///
|
///
|
||||||
|
/// Plugins are applied in the order they are added.
|
||||||
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `plugin` - The boxed filter plugin to add to the chain.
|
/// * `plugin` - The boxed filter plugin to add to the chain.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let mut chain = FilterChain::new();
|
||||||
|
/// chain.add_plugin(Box::new(GrepFilter::new("error".to_string())));
|
||||||
|
/// ```
|
||||||
pub fn add_plugin(&mut self, plugin: Box<dyn FilterPlugin>) {
|
pub fn add_plugin(&mut self, plugin: Box<dyn FilterPlugin>) {
|
||||||
self.plugins.push(plugin);
|
self.plugins.push(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Applies the filter chain to the input and writes to the output.
|
/// Applies the filter chain to the input and writes to the output.
|
||||||
///
|
///
|
||||||
|
/// If no plugins are present, data is copied directly from reader to writer.
|
||||||
|
/// For multiple plugins, intermediate results are buffered.
|
||||||
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `reader` - A mutable reference to the input reader providing the data stream.
|
/// * `reader` - A mutable reference to the input reader providing the data stream.
|
||||||
@@ -184,6 +268,14 @@ impl FilterChain {
|
|||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A `Result` indicating success (`Ok(())`) or failure with an `io::Error` if any filter in the chain fails.
|
/// A `Result` indicating success (`Ok(())`) or failure with an `io::Error` if any filter in the chain fails.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let mut chain = FilterChain::new();
|
||||||
|
/// chain.add_plugin(Box::new(HeadBytesFilter::new(100)));
|
||||||
|
/// chain.filter(&mut input_reader, &mut output_writer)?;
|
||||||
|
/// ```
|
||||||
pub fn filter(&mut self, reader: &mut dyn Read, writer: &mut dyn Write) -> Result<()> {
|
pub fn filter(&mut self, reader: &mut dyn Read, writer: &mut dyn Write) -> Result<()> {
|
||||||
if self.plugins.is_empty() {
|
if self.plugins.is_empty() {
|
||||||
// If no plugins, just copy the input to output
|
// If no plugins, just copy the input to output
|
||||||
|
|||||||
@@ -55,6 +55,22 @@ pub struct ServerConfig {
|
|||||||
/// This struct encapsulates the shared state that is accessible to all request handlers,
|
/// This struct encapsulates the shared state that is accessible to all request handlers,
|
||||||
/// including database connections, file paths, services, and configuration.
|
/// including database connections, file paths, services, and configuration.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
/// Application state shared across all routes.
|
||||||
|
///
|
||||||
|
/// This struct encapsulates the shared state that is accessible to all request handlers,
|
||||||
|
/// including database connections, file paths, services, and configuration.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let state = AppState {
|
||||||
|
/// db: Arc::new(Mutex::new(conn)),
|
||||||
|
/// data_dir: PathBuf::from("/data"),
|
||||||
|
/// item_service: Arc::new(ItemService::new(data_dir.clone())),
|
||||||
|
/// cmd: Arc::new(Mutex::new(Command::new("keep"))),
|
||||||
|
/// settings: Arc::new(settings),
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
/// Database connection wrapped in Arc<Mutex>.
|
/// Database connection wrapped in Arc<Mutex>.
|
||||||
///
|
///
|
||||||
@@ -84,6 +100,24 @@ pub struct AppState {
|
|||||||
/// This generic type is used for all API responses to provide a consistent structure across
|
/// This generic type is used for all API responses to provide a consistent structure across
|
||||||
/// different endpoints.
|
/// different endpoints.
|
||||||
#[derive(Debug, Serialize, Deserialize, ToSchema)]
|
#[derive(Debug, Serialize, Deserialize, ToSchema)]
|
||||||
|
/// Standard API response wrapper containing success status, data payload, and error information.
|
||||||
|
///
|
||||||
|
/// This generic type is used for all API responses to provide a consistent structure across
|
||||||
|
/// different endpoints.
|
||||||
|
///
|
||||||
|
/// # Type Parameters
|
||||||
|
///
|
||||||
|
/// * `T` - The type of the data payload.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let response: ApiResponse<Vec<ItemInfo>> = ApiResponse {
|
||||||
|
/// success: true,
|
||||||
|
/// data: Some(items),
|
||||||
|
/// error: None,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
#[schema(description = "Standard API response wrapper containing success status, data payload, and error information")]
|
#[schema(description = "Standard API response wrapper containing success status, data payload, and error information")]
|
||||||
pub struct ApiResponse<T> {
|
pub struct ApiResponse<T> {
|
||||||
/// Success indicator.
|
/// Success indicator.
|
||||||
@@ -104,6 +138,19 @@ pub struct ApiResponse<T> {
|
|||||||
///
|
///
|
||||||
/// Specialized response for endpoints that return multiple items.
|
/// Specialized response for endpoints that return multiple items.
|
||||||
#[derive(Serialize, Deserialize, ToSchema)]
|
#[derive(Serialize, Deserialize, ToSchema)]
|
||||||
|
/// Response type for list of item information.
|
||||||
|
///
|
||||||
|
/// Specialized response for endpoints that return multiple items.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let response = ItemInfoListResponse {
|
||||||
|
/// success: true,
|
||||||
|
/// data: Some(vec![item_info]),
|
||||||
|
/// error: None,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
pub struct ItemInfoListResponse {
|
pub struct ItemInfoListResponse {
|
||||||
/// Success indicator.
|
/// Success indicator.
|
||||||
///
|
///
|
||||||
@@ -123,6 +170,19 @@ pub struct ItemInfoListResponse {
|
|||||||
///
|
///
|
||||||
/// Specialized response for endpoints that return a single item's details.
|
/// Specialized response for endpoints that return a single item's details.
|
||||||
#[derive(Serialize, Deserialize, ToSchema)]
|
#[derive(Serialize, Deserialize, ToSchema)]
|
||||||
|
/// Response type for single item information.
|
||||||
|
///
|
||||||
|
/// Specialized response for endpoints that return a single item's details.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let response = ItemInfoResponse {
|
||||||
|
/// success: true,
|
||||||
|
/// data: Some(item_info),
|
||||||
|
/// error: None,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
pub struct ItemInfoResponse {
|
pub struct ItemInfoResponse {
|
||||||
/// Success indicator.
|
/// Success indicator.
|
||||||
///
|
///
|
||||||
@@ -142,6 +202,19 @@ pub struct ItemInfoResponse {
|
|||||||
///
|
///
|
||||||
/// Specialized response for endpoints that return item content and related metadata.
|
/// Specialized response for endpoints that return item content and related metadata.
|
||||||
#[derive(Serialize, Deserialize, ToSchema)]
|
#[derive(Serialize, Deserialize, ToSchema)]
|
||||||
|
/// Response type for item content information.
|
||||||
|
///
|
||||||
|
/// Specialized response for endpoints that return item content and related metadata.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let response = ItemContentInfoResponse {
|
||||||
|
/// success: true,
|
||||||
|
/// data: Some(content_info),
|
||||||
|
/// error: None,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
pub struct ItemContentInfoResponse {
|
pub struct ItemContentInfoResponse {
|
||||||
/// Success indicator.
|
/// Success indicator.
|
||||||
///
|
///
|
||||||
@@ -161,6 +234,19 @@ pub struct ItemContentInfoResponse {
|
|||||||
///
|
///
|
||||||
/// Specialized response for metadata-only endpoints.
|
/// Specialized response for metadata-only endpoints.
|
||||||
#[derive(Serialize, Deserialize, ToSchema)]
|
#[derive(Serialize, Deserialize, ToSchema)]
|
||||||
|
/// Response type for metadata.
|
||||||
|
///
|
||||||
|
/// Specialized response for metadata-only endpoints.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let response = MetadataResponse {
|
||||||
|
/// success: true,
|
||||||
|
/// data: Some(meta_map),
|
||||||
|
/// error: None,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
pub struct MetadataResponse {
|
pub struct MetadataResponse {
|
||||||
/// Success indicator.
|
/// Success indicator.
|
||||||
///
|
///
|
||||||
@@ -180,6 +266,19 @@ pub struct MetadataResponse {
|
|||||||
///
|
///
|
||||||
/// Specialized response for system status endpoints.
|
/// Specialized response for system status endpoints.
|
||||||
#[derive(Serialize, Deserialize, ToSchema)]
|
#[derive(Serialize, Deserialize, ToSchema)]
|
||||||
|
/// Response type for status information.
|
||||||
|
///
|
||||||
|
/// Specialized response for system status endpoints.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let response = StatusInfoResponse {
|
||||||
|
/// success: true,
|
||||||
|
/// data: Some(status_info),
|
||||||
|
/// error: None,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
pub struct StatusInfoResponse {
|
pub struct StatusInfoResponse {
|
||||||
/// Success indicator.
|
/// Success indicator.
|
||||||
///
|
///
|
||||||
@@ -200,6 +299,23 @@ pub struct StatusInfoResponse {
|
|||||||
/// This structure represents the full details of an item, combining basic item
|
/// This structure represents the full details of an item, combining basic item
|
||||||
/// properties with associated tags and metadata.
|
/// properties with associated tags and metadata.
|
||||||
#[derive(Serialize, Deserialize, ToSchema)]
|
#[derive(Serialize, Deserialize, ToSchema)]
|
||||||
|
/// Complete information about a stored item including metadata and tags.
|
||||||
|
///
|
||||||
|
/// This structure represents the full details of an item, combining basic item
|
||||||
|
/// properties with associated tags and metadata.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let item_info = ItemInfo {
|
||||||
|
/// id: 42,
|
||||||
|
/// ts: "2023-12-01T15:30:45Z".to_string(),
|
||||||
|
/// size: Some(1024),
|
||||||
|
/// compression: "gzip".to_string(),
|
||||||
|
/// tags: vec!["important".to_string()],
|
||||||
|
/// metadata: HashMap::from([("mime_type".to_string(), "text/plain".to_string())]),
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
#[schema(description = "Complete information about a stored item including metadata and tags")]
|
#[schema(description = "Complete information about a stored item including metadata and tags")]
|
||||||
pub struct ItemInfo {
|
pub struct ItemInfo {
|
||||||
/// Item ID.
|
/// Item ID.
|
||||||
@@ -245,6 +361,20 @@ pub struct ItemInfo {
|
|||||||
/// * `content` - Optional string content (text only).
|
/// * `content` - Optional string content (text only).
|
||||||
/// * `binary` - True if binary content.
|
/// * `binary` - True if binary content.
|
||||||
#[derive(Serialize, Deserialize, ToSchema)]
|
#[derive(Serialize, Deserialize, ToSchema)]
|
||||||
|
/// Item information including content and metadata, with binary detection.
|
||||||
|
///
|
||||||
|
/// This structure provides item details along with its content, handling binary
|
||||||
|
/// content detection and safe string representation.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let content_info = ItemContentInfo {
|
||||||
|
/// metadata: HashMap::from([("mime_type".to_string(), "text/plain".to_string())]),
|
||||||
|
/// content: Some("Hello, world!".to_string()),
|
||||||
|
/// binary: false,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
#[schema(description = "Item information including content and metadata, with binary detection")]
|
#[schema(description = "Item information including content and metadata, with binary detection")]
|
||||||
pub struct ItemContentInfo {
|
pub struct ItemContentInfo {
|
||||||
/// Metadata hashmap.
|
/// Metadata hashmap.
|
||||||
@@ -273,6 +403,15 @@ pub struct ItemContentInfo {
|
|||||||
///
|
///
|
||||||
/// * `tags` - Optional comma-separated tags for filtering.
|
/// * `tags` - Optional comma-separated tags for filtering.
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
/// Query parameters for tags.
|
||||||
|
///
|
||||||
|
/// Structure for handling tag-based query parameters in API requests.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let query = TagsQuery { tags: Some("tag1,tag2".to_string()) };
|
||||||
|
/// ```
|
||||||
pub struct TagsQuery {
|
pub struct TagsQuery {
|
||||||
/// Optional comma-separated tags.
|
/// Optional comma-separated tags.
|
||||||
///
|
///
|
||||||
@@ -291,6 +430,20 @@ pub struct TagsQuery {
|
|||||||
/// * `start` - Optional start index.
|
/// * `start` - Optional start index.
|
||||||
/// * `count` - Optional item limit.
|
/// * `count` - Optional item limit.
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
/// Query parameters for listing items.
|
||||||
|
///
|
||||||
|
/// Structure for pagination and sorting parameters in item listing endpoints.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let query = ListItemsQuery {
|
||||||
|
/// tags: Some("important".to_string()),
|
||||||
|
/// order: Some("newest".to_string()),
|
||||||
|
/// start: Some(0),
|
||||||
|
/// count: Some(10),
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
pub struct ListItemsQuery {
|
pub struct ListItemsQuery {
|
||||||
/// Optional comma-separated tags for filtering.
|
/// Optional comma-separated tags for filtering.
|
||||||
///
|
///
|
||||||
@@ -322,6 +475,21 @@ pub struct ListItemsQuery {
|
|||||||
/// * `stream` - Enable streaming (default false).
|
/// * `stream` - Enable streaming (default false).
|
||||||
/// * `as_meta` - Return as JSON metadata (default false).
|
/// * `as_meta` - Return as JSON metadata (default false).
|
||||||
#[derive(Debug, Deserialize, utoipa::ToSchema)]
|
#[derive(Debug, Deserialize, utoipa::ToSchema)]
|
||||||
|
/// Query parameters for item retrieval.
|
||||||
|
///
|
||||||
|
/// Structure for content retrieval parameters, including binary handling and streaming options.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let query = ItemQuery {
|
||||||
|
/// allow_binary: true,
|
||||||
|
/// offset: 0,
|
||||||
|
/// length: 1024,
|
||||||
|
/// stream: false,
|
||||||
|
/// as_meta: false,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
pub struct ItemQuery {
|
pub struct ItemQuery {
|
||||||
/// Allow binary content (default: true).
|
/// Allow binary content (default: true).
|
||||||
///
|
///
|
||||||
@@ -363,6 +531,22 @@ pub struct ItemQuery {
|
|||||||
/// * `stream` - Enable streaming (default false).
|
/// * `stream` - Enable streaming (default false).
|
||||||
/// * `as_meta` - Return as JSON metadata (default false).
|
/// * `as_meta` - Return as JSON metadata (default false).
|
||||||
#[derive(Debug, Deserialize, utoipa::ToSchema)]
|
#[derive(Debug, Deserialize, utoipa::ToSchema)]
|
||||||
|
/// Query parameters for item content retrieval.
|
||||||
|
///
|
||||||
|
/// Extended query parameters for content-specific operations, including tag filtering.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let query = ItemContentQuery {
|
||||||
|
/// tags: Some("important".to_string()),
|
||||||
|
/// allow_binary: true,
|
||||||
|
/// offset: 0,
|
||||||
|
/// length: 1024,
|
||||||
|
/// stream: false,
|
||||||
|
/// as_meta: false,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
pub struct ItemContentQuery {
|
pub struct ItemContentQuery {
|
||||||
/// Optional comma-separated tags for filtering.
|
/// Optional comma-separated tags for filtering.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -7,11 +7,56 @@ use anyhow::anyhow;
|
|||||||
|
|
||||||
pub struct CompressionService;
|
pub struct CompressionService;
|
||||||
|
|
||||||
|
/// Service for handling compression and decompression of item content.
|
||||||
|
///
|
||||||
|
/// Provides methods to read compressed item files either fully into memory
|
||||||
|
/// or as streaming readers. Supports various compression types via engines.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let service = CompressionService::new();
|
||||||
|
/// let content = service.get_item_content(path, "gzip")?;
|
||||||
|
/// ```
|
||||||
|
|
||||||
impl CompressionService {
|
impl CompressionService {
|
||||||
|
/// Creates a new CompressionService instance.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// A new `CompressionService`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let service = CompressionService::new();
|
||||||
|
/// ```
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self
|
Self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reads and decompresses the full content of an item file into memory.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `item_path` - Path to the compressed item file.
|
||||||
|
/// * `compression` - Compression type string (e.g., "gzip").
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// * `Result<Vec<u8>, CoreError>` - Decompressed content bytes.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// * `CoreError::Compression(...)` - If compression type invalid.
|
||||||
|
/// * `CoreError::Other(...)` - If file open or read fails.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let content = service.get_item_content(item_path, "lz4")?;
|
||||||
|
/// assert_eq!(content.len(), expected_size);
|
||||||
|
/// ```
|
||||||
pub fn get_item_content(&self, item_path: PathBuf, compression: &str) -> Result<Vec<u8>, CoreError> {
|
pub fn get_item_content(&self, item_path: PathBuf, compression: &str) -> Result<Vec<u8>, CoreError> {
|
||||||
let compression_type = CompressionType::from_str(compression)
|
let compression_type = CompressionType::from_str(compression)
|
||||||
.map_err(|e| CoreError::Compression(e.to_string()))?;
|
.map_err(|e| CoreError::Compression(e.to_string()))?;
|
||||||
@@ -25,6 +70,32 @@ impl CompressionService {
|
|||||||
Ok(content)
|
Ok(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Opens a streaming reader for decompressing item content.
|
||||||
|
///
|
||||||
|
/// For Send compatibility, reads full content into memory and returns a Cursor.
|
||||||
|
/// Note: Not suitable for very large files due to memory usage.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `item_path` - Path to the compressed item file.
|
||||||
|
/// * `compression` - Compression type string.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// * `Result<Box<dyn Read + Send>, CoreError>` - Boxed streaming reader.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// * `CoreError::Compression(...)` - If compression type invalid.
|
||||||
|
/// * `CoreError::Other(...)` - If file open or read fails.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let mut reader = service.stream_item_content(item_path, "gzip")?;
|
||||||
|
/// let mut buf = [0; 1024];
|
||||||
|
/// let n = reader.read(&mut buf)?;
|
||||||
|
/// ```
|
||||||
pub fn stream_item_content(
|
pub fn stream_item_content(
|
||||||
&self,
|
&self,
|
||||||
item_path: PathBuf,
|
item_path: PathBuf,
|
||||||
|
|||||||
Reference in New Issue
Block a user