summaryrefslogtreecommitdiff
path: root/src/path_list_editor.rs
diff options
context:
space:
mode:
authorA Farzat <a@farzat.xyz>2026-06-20 03:33:43 +0300
committerA Farzat <a@farzat.xyz>2026-06-20 10:49:32 +0300
commit7f586623ea5139041a09f59f78c6f87cbe937ba8 (patch)
tree93393b6e74dfe5675e8923f6f0e9fac36008bc1b /src/path_list_editor.rs
parent934aca7bf60d5a20e9fbd7b4a2ba1a9ce43fab04 (diff)
downloadrepo2markdown-7f586623ea5139041a09f59f78c6f87cbe937ba8.tar.gz
repo2markdown-7f586623ea5139041a09f59f78c6f87cbe937ba8.zip
Add module/function docs to path_list_editor
Diffstat (limited to 'src/path_list_editor.rs')
-rw-r--r--src/path_list_editor.rs48
1 files changed, 47 insertions, 1 deletions
diff --git a/src/path_list_editor.rs b/src/path_list_editor.rs
index 8d789a4..a740bf2 100644
--- a/src/path_list_editor.rs
+++ b/src/path_list_editor.rs
@@ -1,3 +1,12 @@
+//! Utilities for editing null-separated path lists.
+//!
+//! This module operates on the same null-separated path-list format consumed by `repo2markdown`.
+//! The functions are intended for small Unix-style filter binaries such as `r2md-append`,
+//! `r2md-prepend`, and `r2md-remove`.
+//!
+//! Paths that are kept from stdin are written back using their original byte representation.
+//! Removal compares paths after normalization using the supplied [`Normalizer`].
+
use std::{
collections::HashSet,
ffi::{OsStr, OsString},
@@ -10,13 +19,23 @@ use crate::normalizer::Normalizer;
const NUL: &[u8] = b"\0";
+/// Copies a null-separated path list from `input`, then appends `new_paths`.
+///
+/// Each path in `new_paths` is written as a NUL-terminated entry.
+///
+/// This function is defensive about unterminated input: if `input` is non-empty and does not end
+/// with a NUL byte, a NUL byte is inserted before appended paths are written. If `new_paths` is
+/// empty, this still has the effect of repairing a non-empty unterminated input stream into a
+/// NUL-terminated one.
+///
+/// This function does not normalize, deduplicate, or validate paths.
pub fn append_paths<R: Read, W: Write>(
input: R,
mut output: W,
new_paths: &[OsString],
) -> std::io::Result<()> {
let last_byte_in_input = copy_while_tracking_last_byte(input, &mut output)?;
- // Add NUL if there is input and it does not end in NUL.
+ // Defensively ensure non-empty input is NUL-terminated.
if matches!(last_byte_in_input, Some(byte) if byte != 0) {
output.write_all(NUL)?;
}
@@ -27,6 +46,12 @@ pub fn append_paths<R: Read, W: Write>(
Ok(())
}
+/// Copies all bytes from `input` to `output`, returning the last byte copied.
+///
+/// Returns `Ok(None)` when `input` is empty.
+///
+/// This helper is used by [`append_paths`] to preserve streaming behavior while still detecting
+/// whether the input path list ended with a NUL byte.
fn copy_while_tracking_last_byte<R: Read, W: Write>(
mut input: R,
mut output: W,
@@ -46,6 +71,14 @@ fn copy_while_tracking_last_byte<R: Read, W: Write>(
Ok(last)
}
+/// Prepends `new_paths` before the null-separated path list from `input`.
+///
+/// Each path in `new_paths` is written as a NUL-terminated entry before the original input stream
+/// is copied unchanged.
+///
+/// This function does not normalize, deduplicate, validate, or repair the input stream. In
+/// particular, unlike [`append_paths`], it does not need to inspect whether the input stream is
+/// NUL-terminated because no new path is written after stdin.
pub fn prepend_paths<R: Read, W: Write>(
mut input: R,
mut output: W,
@@ -59,6 +92,19 @@ pub fn prepend_paths<R: Read, W: Write>(
Ok(())
}
+/// Removes paths from a null-separated path list.
+///
+/// The `input` stream is interpreted as a NUL-separated sequence of path entries. Each entry is
+/// normalized with `normalizer` and compared against the normalized form of each path in
+/// `unwanted_paths`.
+///
+/// Entries whose normalized path matches one of the normalized `unwanted_paths` are skipped.
+/// Entries that are kept are written to `output` using their original byte form, followed by a NUL
+/// byte.
+///
+/// Matching is normalization-aware, so paths such as `src/../a.rs`, `./a.rs`, and an absolute path
+/// to `a.rs` may match depending on the supplied [`Normalizer`]. This function does not deduplicate
+/// kept entries.
pub fn remove_paths<R: Read, W: Write>(
mut input: R,
mut output: W,