Initial commit
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
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")
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user