86 lines
2.5 KiB
Rust
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")
|
|
);
|
|
}
|
|
}
|