docs: Add Rustdoc comments for info and mcp modules and grep plugin
Co-authored-by: aider (openai/andrew/openrouter/sonoma-sky-alpha) <aider@aider.chat>
This commit is contained in:
6
PLAN.md
6
PLAN.md
@@ -199,16 +199,16 @@ Private helpers (e.g., internal `fn` without `pub`) are not flagged, as they don
|
|||||||
- `new()` function: Partial.
|
- `new()` function: Partial.
|
||||||
- Impl `MetaPlugin` methods: No docs.
|
- Impl `MetaPlugin` methods: No docs.
|
||||||
|
|
||||||
33. **src/modes/info.rs**
|
33. **src/modes/info.rs** [DONE]
|
||||||
- `mode_info()` function: Partial.
|
- `mode_info()` function: Partial.
|
||||||
- `ItemInfo` struct: No doc.
|
- `ItemInfo` struct: No doc.
|
||||||
- Helpers (`show_item`, `show_item_structured`): No docs.
|
- Helpers (`show_item`, `show_item_structured`): No docs.
|
||||||
|
|
||||||
34. **src/modes/server/mcp/server.rs**
|
34. **src/modes/server/mcp/server.rs** [DONE]
|
||||||
- `KeepMcpServer` struct: No doc.
|
- `KeepMcpServer` struct: No doc.
|
||||||
- `new()` and `handle_request()` methods: No docs.
|
- `new()` and `handle_request()` methods: No docs.
|
||||||
|
|
||||||
35. **src/filter_plugin/grep.rs**
|
35. **src/filter_plugin/grep.rs** [DONE]
|
||||||
- `GrepFilter` struct: Partial.
|
- `GrepFilter` struct: Partial.
|
||||||
- `new()` function: Partial.
|
- `new()` function: Partial.
|
||||||
- Impl `FilterPlugin` methods: No docs.
|
- Impl `FilterPlugin` methods: No docs.
|
||||||
|
|||||||
@@ -4,22 +4,39 @@ use regex::Regex;
|
|||||||
|
|
||||||
/// A filter that matches lines against a regular expression pattern.
|
/// A filter that matches lines against a regular expression pattern.
|
||||||
///
|
///
|
||||||
/// Outputs only lines that match the given regex.
|
/// Outputs only lines that match the given regex. Uses BufRead for line-by-line processing
|
||||||
|
/// and preserves original line endings.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
///
|
||||||
|
/// * `regex` - Compiled regex for matching.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct GrepFilter {
|
pub struct GrepFilter {
|
||||||
regex: Regex,
|
regex: Regex,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new `GrepFilter` with the specified regex pattern.
|
||||||
|
///
|
||||||
|
/// Compiles the pattern using regex crate.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `pattern` - The regular expression pattern (string) used to match lines.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// `Ok(Self)` on success.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns `Err(io::Error::InvalidInput)` if pattern compilation fails (invalid regex).
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let filter = GrepFilter::new("error|warn".to_string())?;
|
||||||
|
/// ```
|
||||||
impl GrepFilter {
|
impl GrepFilter {
|
||||||
/// Creates a new `GrepFilter` with the specified regex pattern.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `pattern` - The regular expression pattern used to match lines.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// Returns an `io::Error` with `InvalidInput` if the regex pattern is invalid.
|
|
||||||
pub fn new(pattern: String) -> Result<Self> {
|
pub fn new(pattern: String) -> Result<Self> {
|
||||||
let regex = Regex::new(&pattern)
|
let regex = Regex::new(&pattern)
|
||||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
|
||||||
@@ -29,23 +46,30 @@ impl GrepFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Filters the input by writing only lines that match the regex pattern.
|
||||||
|
///
|
||||||
|
/// Reads lines from the input and writes matching lines to the output, preserving newlines.
|
||||||
|
/// Uses BufReader for efficient line iteration.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `reader` - A boxed mutable reference to the input reader providing the data stream.
|
||||||
|
/// * `writer` - A boxed mutable reference to the output writer where matching lines are sent.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// `Ok(())` on success.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Propagates `io::Error` from BufRead lines() or writeln! (e.g., read/write failures, UTF-8 issues).
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// filter.filter(Box::new(&mut input), Box::new(&mut output))?;
|
||||||
|
/// ```
|
||||||
impl FilterPlugin for GrepFilter {
|
impl FilterPlugin for GrepFilter {
|
||||||
/// Filters the input by writing only lines that match the regex pattern.
|
|
||||||
///
|
|
||||||
/// Reads lines from the input and writes matching lines to the output, preserving newlines.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `reader` - A boxed mutable reference to the input reader providing the data stream.
|
|
||||||
/// * `writer` - A boxed mutable reference to the output writer where matching lines are sent.
|
|
||||||
///
|
|
||||||
/// # Returns
|
|
||||||
///
|
|
||||||
/// Returns `Ok(())` on success, or an `io::Error` if reading or writing fails.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// Propagates `io::Error` from reading lines or writing output.
|
|
||||||
fn filter(&mut self, mut reader: Box<&mut dyn Read>, mut writer: Box<&mut dyn Write>) -> Result<()> {
|
fn filter(&mut self, mut reader: Box<&mut dyn Read>, mut writer: Box<&mut dyn Write>) -> Result<()> {
|
||||||
let mut buf_reader = std::io::BufReader::new(&mut *reader);
|
let mut buf_reader = std::io::BufReader::new(&mut *reader);
|
||||||
for line in buf_reader.by_ref().lines() {
|
for line in buf_reader.by_ref().lines() {
|
||||||
@@ -58,12 +82,18 @@ impl FilterPlugin for GrepFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Clones this filter into a new boxed instance.
|
/// Clones this filter into a new boxed instance.
|
||||||
///
|
///
|
||||||
/// Creates a new GrepFilter with the same regex pattern.
|
/// Creates a new GrepFilter with the same regex pattern.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A new `Box<dyn FilterPlugin>` representing a clone of this filter.
|
/// A new `Box<dyn FilterPlugin>` representing a clone of this filter.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let cloned = filter.clone_box();
|
||||||
|
/// ```
|
||||||
fn clone_box(&self) -> Box<dyn FilterPlugin> {
|
fn clone_box(&self) -> Box<dyn FilterPlugin> {
|
||||||
Box::new(Self {
|
Box::new(Self {
|
||||||
regex: self.regex.clone(),
|
regex: self.regex.clone(),
|
||||||
@@ -71,12 +101,20 @@ impl FilterPlugin for GrepFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the configuration options for this filter.
|
/// Returns the configuration options for this filter.
|
||||||
///
|
///
|
||||||
/// The only option is the required "pattern" for the regex.
|
/// The only option is the required "pattern" for the regex.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A vector of `FilterOption` describing the filter's configurable parameters.
|
/// A vector containing one `FilterOption` for "pattern" (required, no default).
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let opts = filter.options();
|
||||||
|
/// assert_eq!(opts.len(), 1);
|
||||||
|
/// assert!(opts[0].required);
|
||||||
|
/// ```
|
||||||
fn options(&self) -> Vec<FilterOption> {
|
fn options(&self) -> Vec<FilterOption> {
|
||||||
vec![
|
vec![
|
||||||
FilterOption {
|
FilterOption {
|
||||||
|
|||||||
@@ -13,20 +13,32 @@ use comfy_table::{Cell, Attribute};
|
|||||||
|
|
||||||
/// Displays detailed information about an item or the last item if no ID/tags specified.
|
/// Displays detailed information about an item or the last item if no ID/tags specified.
|
||||||
///
|
///
|
||||||
/// Supports table, JSON, or YAML output formats.
|
/// Supports table, JSON, or YAML output formats. Validates input (at most one ID, no mixing IDs/tags).
|
||||||
|
/// Uses ItemService to fetch the item and displays via helpers.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `cmd` - Mutable Clap command for error handling.
|
/// * `cmd` - Mutable Clap command for error handling and exiting on invalid args.
|
||||||
/// * `settings` - Application settings.
|
/// * `settings` - Application settings for output formatting and human-readable sizes.
|
||||||
/// * `ids` - Mutable vector of item IDs (at most one).
|
/// * `ids` - Mutable vector of item IDs (at most one; cleared if tags used).
|
||||||
/// * `tags` - Mutable vector of tags (mutually exclusive with IDs).
|
/// * `tags` - Mutable vector of tags (mutually exclusive with IDs).
|
||||||
/// * `conn` - Mutable database connection.
|
/// * `conn` - Mutable database connection for querying items.
|
||||||
/// * `data_path` - Path to data directory.
|
/// * `data_path` - Path to data directory for file metadata.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// `Ok(())` on success, or Result with error.
|
/// `Ok(())` on success, or `Err(anyhow::Error)` if item not found or DB query fails.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// * Clap errors if invalid args (e.g., multiple IDs).
|
||||||
|
/// * Anyhow error if no matching item found.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// mode_info(&mut cmd, &settings, &mut vec![123], &mut vec![], &mut conn, data_path)?;
|
||||||
|
/// ```
|
||||||
pub fn mode_info(
|
pub fn mode_info(
|
||||||
cmd: &mut Command,
|
cmd: &mut Command,
|
||||||
settings: &config::Settings,
|
settings: &config::Settings,
|
||||||
@@ -54,6 +66,22 @@ pub fn mode_info(
|
|||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
/// Structured representation of item information for JSON/YAML output.
|
/// Structured representation of item information for JSON/YAML output.
|
||||||
|
///
|
||||||
|
/// This struct serializes item details including ID, timestamp, sizes, compression, tags, and metadata
|
||||||
|
/// for non-table output formats.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
///
|
||||||
|
/// * `id` - The unique item ID.
|
||||||
|
/// * `timestamp` - Formatted timestamp string.
|
||||||
|
/// * `path` - Full file path to the item.
|
||||||
|
/// * `stream_size` - Original uncompressed size in bytes (optional).
|
||||||
|
/// * `stream_size_formatted` - Human-readable stream size.
|
||||||
|
/// * `compression` - Compression type used.
|
||||||
|
/// * `file_size` - Compressed file size in bytes (optional).
|
||||||
|
/// * `file_size_formatted` - Human-readable file size.
|
||||||
|
/// * `tags` - List of associated tags.
|
||||||
|
/// * `meta` - Metadata key-value pairs.
|
||||||
pub struct ItemInfo {
|
pub struct ItemInfo {
|
||||||
id: i64,
|
id: i64,
|
||||||
timestamp: String,
|
timestamp: String,
|
||||||
@@ -67,22 +95,35 @@ pub struct ItemInfo {
|
|||||||
meta: std::collections::HashMap<String, String>,
|
meta: std::collections::HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Displays item information in table format or delegates to structured output.
|
||||||
|
///
|
||||||
|
/// Builds a comfy-table for tabular display or calls structured helper for JSON/YAML.
|
||||||
|
/// Handles file size via metadata and formats tags/meta accordingly.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `item_with_meta` - Item with associated metadata and tags.
|
||||||
|
/// * `settings` - Application settings for formatting (e.g., human-readable sizes).
|
||||||
|
/// * `data_path` - Path to data directory for calculating compressed file size.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// `Ok(())` on success, or `Err(anyhow::Error)` if path resolution fails.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// * Anyhow error if item path cannot be stringified.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// show_item(item_with_meta, &settings, data_path)?;
|
||||||
|
/// ```
|
||||||
fn show_item(
|
fn show_item(
|
||||||
item_with_meta: ItemWithMeta,
|
item_with_meta: ItemWithMeta,
|
||||||
settings: &config::Settings,
|
settings: &config::Settings,
|
||||||
data_path: PathBuf,
|
data_path: PathBuf,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
/// Displays item information in table format or delegates to structured output.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `item_with_meta` - Item with associated metadata and tags.
|
|
||||||
/// * `settings` - Application settings for formatting.
|
|
||||||
/// * `data_path` - Path to data directory for file size calculation.
|
|
||||||
///
|
|
||||||
/// # Returns
|
|
||||||
///
|
|
||||||
/// `Ok(())` on success.
|
|
||||||
let output_format = crate::modes::common::settings_output_format(settings);
|
let output_format = crate::modes::common::settings_output_format(settings);
|
||||||
|
|
||||||
if output_format != OutputFormat::Table {
|
if output_format != OutputFormat::Table {
|
||||||
@@ -157,24 +198,37 @@ fn show_item(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Displays item information in structured JSON or YAML format.
|
||||||
|
///
|
||||||
|
/// Serializes ItemInfo and prints pretty-formatted output. Handles file metadata for sizes.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `item_with_meta` - Item with metadata and tags.
|
||||||
|
/// * `settings` - Settings for size formatting (human-readable).
|
||||||
|
/// * `data_path` - Data path for compressed file size calculation.
|
||||||
|
/// * `output_format` - JSON or YAML (Table is unreachable here).
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// `Ok(())` on success, or `Err(anyhow::Error)` if serialization or path fails.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// * Serde errors during JSON/YAML serialization.
|
||||||
|
/// * Anyhow error if file metadata unavailable.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// show_item_structured(item_with_meta, &settings, data_path, OutputFormat::Json)?;
|
||||||
|
/// ```
|
||||||
fn show_item_structured(
|
fn show_item_structured(
|
||||||
item_with_meta: ItemWithMeta,
|
item_with_meta: ItemWithMeta,
|
||||||
settings: &config::Settings,
|
settings: &config::Settings,
|
||||||
data_path: PathBuf,
|
data_path: PathBuf,
|
||||||
output_format: OutputFormat,
|
output_format: OutputFormat,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
/// Displays item information in structured JSON or YAML format.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `item_with_meta` - Item with metadata and tags.
|
|
||||||
/// * `settings` - Settings for size formatting.
|
|
||||||
/// * `data_path` - Data path for file size.
|
|
||||||
/// * `output_format` - JSON or YAML.
|
|
||||||
///
|
|
||||||
/// # Returns
|
|
||||||
///
|
|
||||||
/// `Ok(())` on success.
|
|
||||||
let item_tags: Vec<String> = item_with_meta.tags.iter().map(|t| t.name.clone()).collect();
|
let item_tags: Vec<String> = item_with_meta.tags.iter().map(|t| t.name.clone()).collect();
|
||||||
let meta_map = item_with_meta.meta_as_map();
|
let meta_map = item_with_meta.meta_as_map();
|
||||||
let item = item_with_meta.item;
|
let item = item_with_meta.item;
|
||||||
|
|||||||
@@ -4,44 +4,61 @@ use serde_json::Value;
|
|||||||
use crate::modes::server::common::AppState;
|
use crate::modes::server::common::AppState;
|
||||||
use super::tools::{KeepTools, ToolError};
|
use super::tools::{KeepTools, ToolError};
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
/// Server handler for MCP (Model Context Protocol) requests.
|
/// Server handler for MCP (Model Context Protocol) requests.
|
||||||
///
|
///
|
||||||
/// Routes requests to appropriate tools and handles responses.
|
/// Routes requests to appropriate tools and handles responses. Clones AppState for tool usage.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
///
|
||||||
|
/// * `state` - The shared application state (DB, config, etc.).
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct KeepMcpServer {
|
pub struct KeepMcpServer {
|
||||||
state: AppState,
|
state: AppState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new `KeepMcpServer` instance.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `state` - The application state containing DB, config, and services.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// A new `KeepMcpServer` instance.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let server = KeepMcpServer::new(app_state);
|
||||||
|
/// ```
|
||||||
impl KeepMcpServer {
|
impl KeepMcpServer {
|
||||||
/// Creates a new `KeepMcpServer` instance.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `state` - The application state containing DB and config.
|
|
||||||
///
|
|
||||||
/// # Returns
|
|
||||||
///
|
|
||||||
/// A new `KeepMcpServer`.
|
|
||||||
pub fn new(state: AppState) -> Self {
|
pub fn new(state: AppState) -> Self {
|
||||||
Self { state }
|
Self { state }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles an MCP request by routing to the appropriate tool.
|
/// Handles an MCP request by routing to the appropriate tool.
|
||||||
///
|
///
|
||||||
/// Supports methods like save_item, get_item, etc.
|
/// Supports methods like "save_item", "get_item", "list_items". Logs the request and delegates to KeepTools.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `method` - The MCP method name.
|
/// * `method` - The MCP method name (string).
|
||||||
/// * `params` - Optional JSON parameters.
|
/// * `params` - Optional JSON parameters as serde_json::Value.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// JSON string response on success, or ToolError.
|
/// `Ok(String)` with JSON-serialized response on success, or `Err(ToolError)` on failure.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returns ToolError::UnknownTool for unsupported methods.
|
/// * ToolError::UnknownTool if method unsupported.
|
||||||
|
/// * Propagates tool-specific errors (e.g., invalid args, DB failures).
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let result = server.handle_request("save_item", Some(params)).await?;
|
||||||
|
/// ```
|
||||||
pub async fn handle_request(&self, method: &str, params: Option<Value>) -> Result<String, ToolError> {
|
pub async fn handle_request(&self, method: &str, params: Option<Value>) -> Result<String, ToolError> {
|
||||||
debug!("MCP: Handling request '{}' with params: {:?}", method, params);
|
debug!("MCP: Handling request '{}' with params: {:?}", method, params);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user