1use super::{dict::Dictionary, err};
2use rust_embed::EmbeddedFile;
4use std::path::PathBuf;
5
6pub struct EmbeddedMeta {
7 pub file: EmbeddedFile,
8 pub name: String,
9}
10
11impl Clone for EmbeddedMeta {
12 fn clone(&self) -> Self {
13 Self {
14 file: EmbeddedFile {
15 data: self.file.data.clone(),
16 metadata: rust_embed::Metadata::__rust_embed_new(
17 self.file.metadata.sha256_hash(),
18 self.file.metadata.last_modified(),
19 ),
20 },
21 name: self.name.clone(),
22 }
23 }
24}
25
26#[derive(Clone)]
28pub struct Config {
29 embed_assets: Vec<EmbeddedMeta>,
30 default_locale: String,
31}
32
33impl Default for Config {
34 fn default() -> Self {
35 Self::global()
36 }
37}
38
39impl Config {
40 pub(crate) fn global() -> Self {
41 Self {
42 default_locale: String::from("en"),
43 embed_assets: Vec::new(),
44 }
45 }
46
47 pub fn with_embed<T: rust_embed::RustEmbed>(mut self) -> Self {
48 T::iter().for_each(|filename| {
49 self.embed_assets.push(EmbeddedMeta {
50 file: T::get(filename.as_ref()).unwrap(),
51 name: filename.to_string(),
52 });
53 });
54 self
55 }
56
57 pub fn finish(self) -> err::Result<Dictionary> {
59 let mut out = Dictionary::default();
60
61 for asset in self.embed_assets {
62 let path = PathBuf::from(asset.name);
63
64 let locale = match path.file_stem().and_then(|x| x.to_str()) {
65 Some(locale) => locale.to_string(),
66 None => continue,
67 };
68
69 let value = match path.extension().and_then(|x| x.to_str()) {
70 Some("json") => {
71 serde_json::from_reader::<_, serde_json::Value>(asset.file.data.as_ref())?
72 }
73 #[cfg(feature = "yaml")]
74 Some("yml") => {
75 serde_yaml::from_reader::<_, serde_json::Value>(asset.file.data.as_ref())?
76 }
77 #[cfg(feature = "toml")]
78 Some("toml") => toml::from_slice::<serde_json::Value>(asset.file.data.as_ref())?,
79 _ => {
80 continue;
81 }
82 };
83
84 out.inner.insert(locale, value);
85 }
86
87 out.default_locale = self.default_locale.clone();
88
89 Ok(out)
90 }
91}