udiffx
Parse and apply an AI-optimized "file changes" envelope that carries multiple file operations in a single block, using unified diff patches for updates.
This crate is designed for LLM output that needs to be machine-parsable and efficient for large files with small edits.
Concept, FILE_CHANGES
A response contains one root container:
<FILE_CHANGES> ... </FILE_CHANGES>
Inside it, you can mix multiple directives:
<FILE_NEW file_path="..."> ... </FILE_NEW><FILE_PATCH file_path="..."> ... </FILE_PATCH>(Unified Diff content)<FILE_RENAME from_path="..." to_path="..." /><FILE_DELETE file_path="..." />
Notes:
- Tags are XML-like but not intended to be strictly XML compliant.
- The parser is tag-based, it extracts only the above tags, content does not need XML escaping.
- Self-closing tags like
<FILE_DELETE ... />are supported.
API overview
The crate exposes two main operations:
- Extract: parse the first
<FILE_CHANGES>block from a string. - Apply: execute the extracted directives against a base directory.
Key public types:
FileChanges, iterable list of directives.FileDirective, one directive (new, patch, rename, delete, fail).ApplyChangesStatus, per-directive success and error reporting.Error/Result<T>, crate error type and alias.
Extracting changes from text
Use extract_file_changes to parse a model response or any input string.
use ;
extract_content parameter:
extract_content = falseparses tags, returnsextruded = None.extract_content = truealso returns the input with the extracted<FILE_CHANGES>block removed asSome(String).
Applying changes to disk
Use apply_file_changes to execute directives relative to a base directory.
- All file paths are treated as relative to
base_dir. - The crate performs basic path safety checks to ensure operations stay within
base_dir. - Patch application uses
diffy(Unified Diff parsing and application).
use SPath;
use ;
Directive behavior
FILE_NEW: creates or overwrites a file, parent directories are created.FILE_PATCH: reads the target file, applies a unified diff, writes the result back.FILE_RENAME: renames/movesfrom_pathtoto_path.FILE_DELETE: removes a file or directory recursively.
If extraction fails for a directive (unknown tag, missing attribute, etc.), the directive is represented as:
FileDirective::Fail { kind, file_path, error_msg }
When applying, Fail directives always yield an error for that directive and are reported via ApplyChangesInfo.
Format tips for LLM output
- Always emit exactly one
<FILE_CHANGES>block when you intend to apply changes. - Prefer
FILE_PATCHfor small edits to large files. - Use self-closing tags for rename and delete when convenient:
<FILE_RENAME from_path="a" to_path="b" /><FILE_DELETE file_path="path" />
License
MIT OR Apache-2.0