Merge branch 'main' into main

This commit is contained in:
github-actions[bot]
2026-04-29 18:23:25 +00:00
committed by GitHub

View File

@@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::fs;
use std::io::{Error, ErrorKind, Write};
use std::path::Path;
@@ -39,6 +40,24 @@ fn read_existing_note_bytes(path: &Path) -> Result<Vec<u8>, String> {
fs::read(path).map_err(|e| format!("Failed to read {}: {}", path.display(), e))
}
struct RawNotePath<'a>(&'a str);
impl<'a> RawNotePath<'a> {
fn is_windows_verbatim(&self) -> bool {
self.0.starts_with(r"\\?\") || self.0.starts_with(r"\??\")
}
fn normalized_for_file_io(&self) -> Cow<'a, str> {
if !self.is_windows_verbatim() {
return Cow::Borrowed(self.0);
}
if !self.0.contains('/') {
return Cow::Borrowed(self.0);
}
Cow::Owned(self.0.replace('/', r"\"))
}
}
#[derive(Clone, Copy)]
enum NoteIoOperation {
Save,
@@ -112,7 +131,8 @@ fn validate_save_path(file_path: &Path, display_path: &str) -> Result<(), String
/// Write content to a note file. Creates parent directory if needed, validates path,
/// then writes content to disk.
pub fn save_note_content(path: &str, content: &str) -> Result<(), String> {
let file_path = Path::new(path);
let normalized_path = RawNotePath(path).normalized_for_file_io();
let file_path = Path::new(normalized_path.as_ref());
if let Some(parent) = file_path.parent() {
if !parent.exists() {
fs::create_dir_all(parent).map_err(|e| {
@@ -127,7 +147,8 @@ pub fn save_note_content(path: &str, content: &str) -> Result<(), String> {
/// Create a new note file without overwriting any existing file.
pub fn create_note_content(path: &str, content: &str) -> Result<(), String> {
let file_path = Path::new(path);
let normalized_path = RawNotePath(path).normalized_for_file_io();
let file_path = Path::new(normalized_path.as_ref());
if let Some(parent) = file_path.parent() {
if !parent.exists() {
fs::create_dir_all(parent).map_err(|e| {
@@ -166,6 +187,16 @@ mod tests {
assert!(!message.contains("os error 123"));
}
#[test]
fn normalizes_extended_windows_paths_before_file_io() {
let path = r"\\?\C:\Users\alex\Documents\Tolaria/Getting Started/untitled-project.md";
assert_eq!(
RawNotePath(path).normalized_for_file_io(),
r"\\?\C:\Users\alex\Documents\Tolaria\Getting Started\untitled-project.md"
);
}
#[test]
fn note_content_matches_detects_external_edits() {
let dir = tempfile::TempDir::new().unwrap();