Files
RaymarchingEditor/src/io/dialog.rs
T
Efim Beshmenev 0c36122baa Initial commit
2026-07-19 00:19:41 +03:00

86 lines
2.5 KiB
Rust

use std::path::{Path, PathBuf};
use rfd::FileDialog;
use winit::window::Window;
const DEFAULT_FILE_NAME: &str = "map.json";
/// Show the platform-native Save dialog. The caller owns the returned path and
/// decides when to write, which keeps dialogs entirely out of unit tests.
pub fn choose_map_save_path(window: &Window, current: Option<&Path>) -> Option<PathBuf> {
let mut dialog = map_dialog(window, "Сохранить карту");
if let Some(directory) = starting_directory(current) {
dialog = dialog.set_directory(directory);
}
let suggested_name = current
.and_then(Path::file_name)
.and_then(|name| name.to_str())
.unwrap_or(DEFAULT_FILE_NAME);
dialog
.set_file_name(suggested_name)
.save_file()
.map(ensure_json_extension)
}
/// Show the platform-native Open dialog for one versioned JSON map.
pub fn choose_map_open_path(window: &Window, current: Option<&Path>) -> Option<PathBuf> {
let mut dialog = map_dialog(window, "Открыть карту");
if let Some(directory) = starting_directory(current) {
dialog = dialog.set_directory(directory);
}
dialog.pick_file()
}
fn map_dialog(window: &Window, title: &str) -> FileDialog {
FileDialog::new()
.set_parent(window)
.set_title(title)
.add_filter("Карта Ray Marching (JSON)", &["json"])
}
fn starting_directory(current: Option<&Path>) -> Option<PathBuf> {
current
.and_then(|path| {
if path.is_dir() {
Some(path)
} else {
path.parent()
}
})
.filter(|path| !path.as_os_str().is_empty())
.map(Path::to_owned)
.or_else(|| std::env::current_dir().ok())
}
pub(crate) fn ensure_json_extension(mut path: PathBuf) -> PathBuf {
let is_json = path
.extension()
.and_then(|extension| extension.to_str())
.is_some_and(|extension| extension.eq_ignore_ascii_case("json"));
if !is_json {
path.set_extension("json");
}
path
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn save_path_gets_one_json_extension() {
assert_eq!(
ensure_json_extension(PathBuf::from("level")),
PathBuf::from("level.json")
);
assert_eq!(
ensure_json_extension(PathBuf::from("level.JSON")),
PathBuf::from("level.JSON")
);
assert_eq!(
ensure_json_extension(PathBuf::from("level.txt")),
PathBuf::from("level.json")
);
}
}