Merge branch 'main' into main
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user