glossa_shared/
load_bincode.rs

1use std::{
2  ffi::OsStr,
3  path::{Path, PathBuf},
4  sync::OnceLock,
5};
6
7use compact_str::ToCompactString;
8use glossa_dsl::error::ResolverResult;
9use lang_id::LangID;
10use log::debug;
11use tap::Pipe;
12
13use crate::{
14  decode::file::{decode_file_to_maps, decode_single_file_to_flatten_map},
15  type_aliases::L10nMaps,
16};
17
18// pub trait LoadBincode {
19//   fn get_bincode_dir() -> Option<PathBuf>;
20
21pub fn list_bincode_files(bincode_dir: Option<&Path>) -> Option<Vec<PathBuf>> {
22  bincode_dir?
23    .read_dir()
24    .ok()?
25    .flatten()
26    .map(|x| x.path())
27    .filter(|x| !x.is_dir())
28    .collect::<Vec<_>>()
29    .pipe(|x| (!x.is_empty()).then_some(x))
30}
31
32pub fn list_static_bincode_files(
33  bincode_dir: Option<&Path>,
34) -> Option<&'static [PathBuf]> {
35  static V: OnceLock<Option<Vec<PathBuf>>> = OnceLock::new();
36  V.get_or_init(|| list_bincode_files(bincode_dir))
37    .as_deref()
38}
39
40pub fn try_load_files<P: AsRef<Path>>(files: &[P]) -> ResolverResult<L10nMaps> {
41  let all = OsStr::new("all");
42  log::debug!("Loading bincode data ...");
43
44  let iter = files.iter().map(AsRef::as_ref);
45
46  match iter
47    .clone()
48    .find(|x| x.file_stem() == Some(all))
49  {
50    Some(p) => {
51      debug!("load: all.bincode");
52      decode_file_to_maps(p)
53    }
54    _ => iter
55      .filter_map(|x| {
56        decode_single_file_to_flatten_map(x)
57          .ok()
58          .and_then(|data| {
59            x.file_stem()
60              .inspect(|s| debug!("file-stem: {s:?}"))
61              .and_then(|s| s.to_str())
62              .map(|lang| (lang.to_compact_string(), data))
63          })
64      })
65      .collect::<L10nMaps>()
66      .pipe(Ok),
67  }
68}
69
70pub fn merge_locales(
71  lhs: Option<&L10nMaps>,
72  rhs: Option<&[LangID]>,
73) -> Option<Box<[LangID]>> {
74  let builtin = rhs
75    .into_iter()
76    .flatten()
77    .cloned();
78
79  let locales = lhs?
80    .keys()
81    .inspect(|x| debug!("language: {x}"))
82    .filter_map(|x| x.parse::<LangID>().ok())
83    .chain(builtin)
84    .collect::<ahash::HashSet<_>>() // dedup
85    .into_iter()
86    .collect();
87
88  Some(locales)
89}