Skip to main content

patch_task_line

Function patch_task_line 

Source
pub fn patch_task_line(
    source: &str,
    line_number: u32,
    expected: &str,
    status: TaskStatus,
    now: Option<NaiveDateTime>,
) -> Result<PatchedSource, TaskPatchError>
Expand description

Rewrites one task line of a markdown source, checking first that the line is still what the caller last saw.

This is the whole body of POST /.mbr/task, minus the I/O: the caller reads the file, hands the text here, and writes back PatchedSource::source. Keeping it pure is what makes the awkward parts — line addressing, the terminator, the expected comparison — testable without a filesystem.

line_number is 1-based. expected is compared to the line on disk byte-for-byte modulo the line terminator, so a client that captured the line with or without its \n (or \r\n) is treated the same.

Only the one line is touched: no other byte of source moves, the patched line keeps its own terminator, and a file that did not end in a newline still does not.

§Examples

use chrono::NaiveDate;
use mbr_core::tasks::{TaskStatus, patch_task_line};

let now = NaiveDate::from_ymd_opt(2026, 8, 4)
    .and_then(|d| d.and_hms_opt(14, 32, 0))
    .unwrap();
let source = "# Notes\r\n- [ ] ship it\r\n- [ ] later\r\n";

let patched =
    patch_task_line(source, 2, "- [ ] ship it", TaskStatus::Done, Some(now)).unwrap();
assert_eq!(patched.text, "- [x] ship it @done(2026-08-04 14:32)");
assert_eq!(
    patched.source,
    "# Notes\r\n- [x] ship it @done(2026-08-04 14:32)\r\n- [ ] later\r\n"
);