veloren/voxygen/i18n/src/path.rs
Marcel Märtens ee704e171d move translation check to seperate ci step
note: TAGUUID is used to avoid sqlinjections by choosing a branch name
2021-08-02 20:11:02 +02:00

142 lines
4.4 KiB
Rust

use std::path::{Path, PathBuf};
pub(crate) const LANG_MANIFEST_FILE: &str = "_manifest";
pub(crate) const LANG_EXTENSION: &str = "ron";
#[derive(Clone)]
pub struct BasePath {
///repo part, git main folder
root_path: PathBuf,
///relative path to i18n path which contains, currently
/// 'assets/voxygen/i18n'
relative_i18n_root_path: PathBuf,
///i18n_root_folder
cache: PathBuf,
}
impl BasePath {
pub fn new(root_path: &Path) -> Self {
let relative_i18n_root_path = Path::new("assets/voxygen/i18n").to_path_buf();
let cache = root_path.join(&relative_i18n_root_path);
assert!(
cache.is_dir(),
"i18n_root_path folder doesn't exist, something is wrong!"
);
Self {
root_path: root_path.to_path_buf(),
relative_i18n_root_path,
cache,
}
}
pub fn root_path(&self) -> &Path { &self.root_path }
pub fn relative_i18n_root_path(&self) -> &Path { &self.relative_i18n_root_path }
/// absolute path to `relative_i18n_root_path`
pub fn i18n_root_path(&self) -> &Path { &self.cache }
pub fn i18n_path(&self, language_identifier: &str) -> LangPath {
LangPath::new(self, language_identifier)
}
/// List localization directories
pub fn i18n_directories(&self) -> Vec<LangPath> {
std::fs::read_dir(&self.cache)
.unwrap()
.map(|res| res.unwrap())
.filter(|e| e.file_type().unwrap().is_dir())
.map(|e| LangPath::new(self, e.file_name().to_str().unwrap()))
.collect()
}
}
impl core::fmt::Debug for BasePath {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}", &self.cache)
}
}
#[derive(Clone)]
pub struct LangPath {
base: BasePath,
/// `en`, `de_DE`, `fr_FR`, etc..
language_identifier: String,
/// i18n_path
cache: PathBuf,
}
impl LangPath {
fn new(base: &BasePath, language_identifier: &str) -> Self {
let cache = base.i18n_root_path().join(language_identifier);
if !cache.is_dir() {
panic!("language folder '{}' doesn't exist", language_identifier);
}
Self {
base: base.clone(),
language_identifier: language_identifier.to_owned(),
cache,
}
}
pub fn base(&self) -> &BasePath { &self.base }
pub fn language_identifier(&self) -> &str { &self.language_identifier }
///absolute path to `i18n_root_path` + `language_identifier`
pub fn i18n_path(&self) -> &Path { &self.cache }
/// fragment or manifest file, based on a path
pub fn sub_path(&self, sub_path: &Path) -> PathBuf { self.cache.join(sub_path) }
/// fragment or manifest file, based on a string without extension
pub fn file(&self, name_without_extension: &str) -> PathBuf {
self.cache
.join(format!("{}.{}", name_without_extension, LANG_EXTENSION))
}
/// return all fragments sub_pathes
pub(crate) fn fragments(&self) -> Result<Vec</* sub_path */ PathBuf>, std::io::Error> {
let mut result = vec![];
recursive_fragments_paths_in_language(self, Path::new(""), &mut result)?;
Ok(result)
}
}
//unwraps cant fail as they are in same Path
fn recursive_fragments_paths_in_language(
lpath: &LangPath,
subfolder: &Path,
result: &mut Vec<PathBuf>,
) -> Result<(), std::io::Error> {
let manifest_path = PathBuf::from(&format!("{}.{}", LANG_MANIFEST_FILE, LANG_EXTENSION));
let template_path = PathBuf::from(&format!("{}.{}", "template", LANG_EXTENSION));
let search_dir = lpath.sub_path(subfolder);
for fragment_file in search_dir.read_dir()?.flatten() {
let file_type = fragment_file.file_type()?;
let full_path = fragment_file.path();
let relative_path = full_path.strip_prefix(lpath.i18n_path()).unwrap();
if file_type.is_dir() {
recursive_fragments_paths_in_language(lpath, relative_path, result)?;
} else if file_type.is_file()
&& relative_path != manifest_path
&& relative_path != template_path
{
result.push(relative_path.to_path_buf());
}
}
Ok(())
}
impl core::fmt::Debug for LangPath {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"{:?}",
self.base
.relative_i18n_root_path
.join(&self.language_identifier)
)
}
}