Repository: nushell/nushell
File: crates/nu-command/src/filesystem/save.rs (Rust)

Code before:
                Err(std::io::ErrorKind::IsADirectory.into())
            } else {
                std::fs::File::create(path)
            }
            #[cfg(not(target_os = "windows"))]
            std::fs::File::create(path)
        }
    };

    match file {
        Ok(file) => Ok(file),
        Err(err) => {
            // In caase of NotFound, search for the missing parent directory.
            // This also presents a TOCTOU (or TOUTOC, technically?)
            if err.kind() == std::io::ErrorKind::NotFound {
                if let Some(missing_component) =
                    path.ancestors().skip(1).filter(|dir| !dir.exists()).last()
                {
                    let components_to_remove = path
                        .strip_prefix(missing_component)
                        .expect("Stripping ancestor from a path should never fail")
                        .as_os_str()
                        .as_encoded_bytes();

                    return Err(ShellError::Io(IoError::new(
                        ErrorKind::DirectoryNotFound,
                        engine_state
                            .span_match_postfix(span, components_to_remove)
                            .map(|(pre, _post)| pre)
                            .unwrap_or(span),
                        PathBuf::from(missing_component),
                    )));
                }
            }

            Err(ShellError::Io(IoError::new(err, span, PathBuf::from(path))))
        }
    }
}

/// Get output file and optional stderr file
fn get_files(
    engine_state: &EngineState,
    path: &Spanned<PathBuf>,
    stderr_path: Option<&Spanned<PathBuf>>,
    append: bool,
    force: bool,
) -> Result<(File, Option<File>), ShellError> {
    // First check both paths
    let (path, path_span) = prepare_path(path, append, force)?;
    let stderr_path_and_span = stderr_path

Review comment (refactor):
You are extracting the suffix so it can deal with relative paths?

Otherwise it may look like doing more work then necessary.

Code after:
                Err(std::io::ErrorKind::IsADirectory.into())
            } else {
                std::fs::File::create(path)
            }
            #[cfg(not(target_os = "windows"))]
            std::fs::File::create(path)
        }
    };

    match file {
        Ok(file) => Ok(file),
        Err(err) => {
            // In caase of NotFound, search for the missing parent directory.
            // This also presents a TOCTOU (or TOUTOC, technically?)
            if err.kind() == std::io::ErrorKind::NotFound {
                if let Some(missing_component) =
                    path.ancestors().skip(1).filter(|dir| !dir.exists()).last()
                {
                    // By looking at the postfix to remove, rather than the prefix
                    // to keep, we are able to handle relative paths too.
                    let components_to_remove = path
                        .strip_prefix(missing_component)
                        .expect("Stripping ancestor from a path should never fail")
                        .as_os_str()
                        .as_encoded_bytes();

                    return Err(ShellError::Io(IoError::new(
                        ErrorKind::DirectoryNotFound,
                        engine_state
                            .span_match_postfix(span, components_to_remove)
                            .map(|(pre, _post)| pre)
                            .unwrap_or(span),
                        PathBuf::from(missing_component),
                    )));
                }
            }

            Err(ShellError::Io(IoError::new(err, span, PathBuf::from(path))))
        }
    }
}

/// Get output file and optional stderr file
fn get_files(
    engine_state: &EngineState,
    path: &Spanned<PathBuf>,
    stderr_path: Option<&Spanned<PathBuf>>,
    append: bool,
    force: bool,
) -> Result<(File, Option<File>), ShellError> {
    // First check both paths