Skip to content

Latest commit

 

History

History
138 lines (99 loc) · 3.68 KB

File metadata and controls

138 lines (99 loc) · 3.68 KB

code-parser

A Rust library for parsing and applying code blocks from AI agent responses.

Features

  • Code Block Extraction: Parse markdown code blocks with language detection
  • Filename Detection: Automatically extract filenames from AI response context
  • Language Inference: Map file extensions to programming languages
  • Security: Path traversal prevention and filename sanitization
  • Edit Instructions: Parse structured edit instructions ("change X to Y")
  • File Application: Optionally write extracted code to files (with fs feature)

Installation

Add to your Cargo.toml:

[dependencies]
code-parser = { path = "tools/rust/code-parser" }

# Enable file system operations
code-parser = { path = "tools/rust/code-parser", features = ["fs"] }

Usage

Basic Code Block Extraction

use code_parser::CodeParser;

let response = r#"
Here's a Python function:

```python
def hello():
    print("Hello, world!")

"#;

let blocks = CodeParser::extract_code_blocks(response); for block in blocks { println!("Language: {}", block.language); println!("Content: {}", block.content); if let Some(filename) = block.filename { println!("File: {}", filename); } }


### Language Inference

```rust
use code_parser::CodeParser;

assert_eq!(CodeParser::infer_language("main.rs"), "rust");
assert_eq!(CodeParser::infer_language("script.py"), "python");
assert_eq!(CodeParser::infer_language("app.tsx"), "tsx");

Filename Sanitization

use code_parser::CodeParser;

// Valid filenames
assert!(CodeParser::sanitize_filename("src/main.rs").is_ok());
assert!(CodeParser::sanitize_filename("./test.py").is_ok());

// Blocked paths (security)
assert!(CodeParser::sanitize_filename("/etc/passwd").is_err());
assert!(CodeParser::sanitize_filename("../secret.txt").is_err());

Parse Edit Instructions

use code_parser::CodeParser;

let response = r#"In file `main.py`, change `print("hello")` to `print("goodbye")`"#;

let instructions = CodeParser::parse_edit_instructions(response);
for inst in instructions {
    println!("File: {}, Replace '{}' with '{}'", inst.file, inst.old, inst.new);
}

Apply Code Blocks to Files (requires fs feature)

use code_parser::CodeParser;
use std::path::Path;

let response = r#"
Create file `src/utils.py`:

```python
def helper():
    pass

"#;

let (blocks, results) = CodeParser::extract_and_apply(response, Path::new(".")); for (file, status) in results { println!("{}: {}", file, status); }


## Security Features

The library includes several security measures:

1. **Absolute Path Rejection**: Paths starting with `/` or drive letters are blocked
2. **Parent Directory Traversal**: Paths containing `..` are blocked
3. **Special Character Filtering**: Null bytes and newlines in filenames are rejected
4. **Base Path Enforcement**: When writing files, all paths are verified to be within the specified base directory

## API Reference

### Types

- `CodeBlock` - Represents an extracted code block
- `EditInstruction` - Represents a parsed edit instruction
- `CodeParserError` - Error type for parsing/application operations

### Functions

- `CodeParser::extract_code_blocks(response)` - Extract all code blocks
- `CodeParser::infer_language(filename)` - Infer language from extension
- `CodeParser::sanitize_filename(filename)` - Sanitize and validate a filename
- `CodeParser::parse_edit_instructions(response)` - Parse edit instructions
- `CodeParser::apply_code_blocks(blocks, base_path)` - Write blocks to files (fs feature)
- `CodeParser::extract_and_apply(response, base_path)` - Combined operation (fs feature)

## License

Part of the template-repo project. See repository LICENSE file.