pdx_syntax/
localization.rs

1//! # Syntax of paradox localization file
2//!
3//! Paradox mainly uses `yml` as the format of their localizaiton files. However,
4//! there is a weird syntax in files. Specifically, the ':' might be followed with
5//! a number. For example: `ABC:0 "This is ABC"`. I haven't worked out the meaning
6//! of the number, however, it adds no difficulty to the parser. Here the parser
7//! just gives an ambiguous result.
8//!
9use serde::{Deserialize, Serialize};
10
11use lalrpop_util::lalrpop_mod;
12lalrpop_mod!(localization_syn);
13
14/// A localization file. Begin with a language specifier, following with a list of localization entries.
15#[derive(Serialize, Deserialize, Debug)]
16pub struct LocList {
17    pub lang: Loc,
18    pub entries: Vec<Entry>,
19}
20
21/// Language, e.g., `l_english:`.
22///
23/// This is always the first line of a localization file.
24#[derive(Serialize, Deserialize)]
25pub struct Loc(String);
26
27impl core::ops::Deref for Loc {
28    type Target = String;
29    fn deref(&self) -> &Self::Target {
30        &self.0
31    }
32}
33
34impl core::ops::DerefMut for Loc {
35    fn deref_mut(&mut self) -> &mut Self::Target {
36        &mut self.0
37    }
38}
39
40/// Entry, e.g., `ABC:0 "This is ABC"`.
41///
42/// All non-empty lines except the first line are entries.
43#[derive(Serialize, Deserialize)]
44pub struct Entry {
45    pub key: String,
46    pub num: Option<u8>,
47    pub value: String,
48}
49
50super::fn_parse_file!(LocList, localization_syn::LocListParser);
51
52pub mod types {
53    //! Expose the types ([`LocList`], [`Loc`], [`Entry`]) to the outside.
54    //! For convenience.
55    //!
56    pub use super::{Entry, Loc, LocList};
57}
58
59/* ------------------------- impl Debug ------------------------- */
60
61impl core::fmt::Debug for Loc {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        write!(f, "{}:", self.0)
64    }
65}
66
67impl core::fmt::Debug for Entry {
68    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69        match self.num {
70            Some(n) => write!(f, "{}:{} {}", self.key, n, self.value),
71            None => write!(f, "{}: {}", self.key, self.value),
72        }
73    }
74}
75
76/* ------------------------ impl Display ------------------------ */
77// [`Display`] is used to dump the AST back to files.
78
79impl core::fmt::Display for LocList {
80    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81        writeln!(f, "{:?}", self.lang)?;
82        for entry in &self.entries {
83            // Manually add indent.
84            writeln!(f, "  {:?}", entry)?;
85        }
86        Ok(())
87    }
88}