veloren_client_i18n/
raw.rs

1use crate::{
2    Fonts, LanguageMetadata,
3    assets::{
4        Asset, AssetCache, BoxedError, DirLoadable, FileAsset, Ron, SharedString, Source,
5        source::DirEntry,
6    },
7};
8use serde::{Deserialize, Serialize};
9use std::borrow::Cow;
10
11/// Localization metadata from manifest file
12/// See `Language` for more info on each attributes
13#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
14pub(crate) struct Manifest {
15    pub(crate) fonts: Fonts,
16    pub(crate) metadata: LanguageMetadata,
17}
18
19impl Asset for Manifest {
20    fn load(cache: &AssetCache, specifier: &SharedString) -> Result<Self, BoxedError> {
21        Ok(cache
22            .load::<Ron<Self>>(specifier)
23            .map(|v| v.read().clone().into_inner())?)
24    }
25}
26
27impl DirLoadable for Manifest {
28    fn select_ids(
29        cache: &AssetCache,
30        specifier: &SharedString,
31    ) -> std::io::Result<Vec<SharedString>> {
32        let mut specifiers = Vec::new();
33
34        let source = cache.source();
35        source.read_dir(specifier, &mut |entry| {
36            if let DirEntry::Directory(spec) = entry {
37                let manifest_spec = [spec, ".", "_manifest"].concat();
38
39                if source.exists(DirEntry::File(&manifest_spec, "ron")) {
40                    specifiers.push(manifest_spec.into());
41                }
42            }
43        })?;
44
45        Ok(specifiers)
46    }
47}
48
49// Newtype wrapper representing fluent resource.
50//
51// NOTE:
52// We store String, that later converted to FluentResource.
53// We can't do it at load time, because we might want to do utf8 to ascii
54// conversion and we know it only after we've loaded language manifest.
55//
56// Alternative solution is to make it hold Rc/Arc around FluentResource,
57// implement methods that give us mutable control around resource entries,
58// but doing it to eliminate Clone that happens N per programm life seems as
59// overengineering.
60//
61// N is time of fluent files, so about 20 for English and the same for target
62// localisation.
63#[derive(Clone)]
64pub(crate) struct Resource {
65    pub(crate) src: String,
66}
67
68impl FileAsset for Resource {
69    const EXTENSION: &'static str = "ftl";
70
71    fn from_bytes(bytes: Cow<[u8]>) -> Result<Self, BoxedError> {
72        Ok(Self {
73            src: String::from_utf8(bytes.into())?,
74        })
75    }
76}