Skip to content

Commit

Permalink
system/locale: Split iso_639 into 2 files, cleanup and reorganise
Browse files Browse the repository at this point in the history
Signed-off-by: Ikey Doherty <[email protected]>
  • Loading branch information
ikeycode committed Jun 17, 2024
1 parent 90998e1 commit b91a7c1
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 159 deletions.
22 changes: 22 additions & 0 deletions src/system/locale/iso_3166.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use serde::Deserialize;

use super::Territory;

/// Wrap the document stream from JSON into referenced
/// entries in the input text
#[derive(Deserialize)]
Expand Down Expand Up @@ -43,6 +45,26 @@ pub struct Entry<'a> {
pub official_name: Option<&'a str>,
}

impl From<&Entry<'_>> for Territory {
fn from(value: &Entry) -> Self {
if let Some(display) = value.official_name {
Self {
code: value.code3.into(),
code2: value.code2.into(),
display_name: display.into(),
flag: value.flag.into(),
}
} else {
Self {
code: value.code3.into(),
code2: value.code2.into(),
display_name: value.name.into(),
flag: value.flag.into(),
}
}
}
}

#[cfg(test)]
mod tests {
use super::Document;
Expand Down
88 changes: 88 additions & 0 deletions src/system/locale/iso_639_2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// SPDX-FileCopyrightText: Copyright © 2024 Serpent OS Developers
//
// SPDX-License-Identifier: MPL-2.0

//! Parsing for ISO-639 files from iso-codes
//! Essentially, loading of languages
use serde::Deserialize;

use super::Language;

/// JSON document for ISO-639-2
#[derive(Deserialize)]
pub struct Document<'a> {
#[serde(rename = "639-2", borrow)]
pub entries: Vec<Entry<'a>>,
}

/// A single entry in the JSON document
#[derive(Deserialize)]
pub struct Entry<'a> {
#[serde(rename = "alpha_2", borrow)]
pub code2: Option<&'a str>,

#[serde(rename = "alpha_3", borrow)]
pub code3: &'a str,

/// Official display name
#[serde(borrow)]
pub name: &'a str,

/// Common name (optional)
#[serde(borrow)]
pub common_name: Option<&'a str>,

/// Three letter bibliographic
pub bibliographic: Option<&'a str>,
}

impl From<&Entry<'_>> for Language {
/// Convert iso entry into Language
fn from(value: &Entry<'_>) -> Self {
Self {
code: value.code3.into(),
code2: value.code2.map(|v| v.into()),
display_name: value.name.into(),
inverted_name: None,
}
}
}

#[cfg(test)]
mod tests {
use super::Document;

#[test]
fn load_iso_639_2() {
const TEST_DATA: &str = r#"
{
"639-2": [
{
"alpha_2": "gd",
"alpha_3": "gla",
"name": "Gaelic; Scottish Gaelic"
},
{
"alpha_2": "ga",
"alpha_3": "gle",
"name": "Irish"
},
{
"alpha_2": "gl",
"alpha_3": "glg",
"name": "Galician"
}
]
}
"#;

let loaded = serde_json::from_str::<Document>(TEST_DATA).expect("Failed to decode ISO-639-2 data");
let ga = loaded
.entries
.iter()
.find(|i| i.code3 == "gle")
.expect("Failed to find GLE");
assert_eq!(ga.name, "Irish");
}
}
97 changes: 26 additions & 71 deletions src/system/locale/iso_639.rs → src/system/locale/iso_639_3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,16 @@
//
// SPDX-License-Identifier: MPL-2.0

//! Parsing for ISO-639 files from iso-codes
//! Essentially, loading of languages
//! Parsing for ISO-639-3 JSON files
use serde::Deserialize;

/// Wrap the document stream from JSON into referenced
/// entries in the input text
#[derive(Deserialize)]
pub struct DocumentTwoCode<'a> {
#[serde(rename = "639-2", borrow)]
pub entries: Vec<EntryTwoCode<'a>>,
}

/// A two-letter code entry
#[derive(Deserialize)]
pub struct EntryTwoCode<'a> {
#[serde(rename = "alpha_2", borrow)]
pub code2: Option<&'a str>,

#[serde(rename = "alpha_3", borrow)]
pub code3: &'a str,

/// Official display name
#[serde(borrow)]
pub name: &'a str,

/// Common name (optional)
#[serde(borrow)]
pub common_name: Option<&'a str>,

/// Three letter bibliographic
pub bibliographic: Option<&'a str>,
}
use super::Language;

/// JSON document for 639-3
#[derive(Deserialize)]
pub struct DocumentThreeCode<'a> {
pub struct Document<'a> {
#[serde(rename = "639-3", borrow)]
pub entries: Vec<EntryThreeCode<'a>>,
pub entries: Vec<Entry<'a>>,
}

/// Language scope
Expand Down Expand Up @@ -71,8 +43,9 @@ pub enum Kind {
Special,
}

/// Single entry in the JSON document
#[derive(Deserialize)]
pub struct EntryThreeCode<'a> {
pub struct Entry<'a> {
/// Three letter code
#[serde(rename = "alpha_3", borrow)]
pub code: &'a str,
Expand Down Expand Up @@ -104,45 +77,28 @@ pub struct EntryThreeCode<'a> {
pub common_name: Option<&'a str>,
}

#[cfg(test)]
mod tests {
use super::{DocumentThreeCode, DocumentTwoCode, Kind, Scope};

#[test]
fn load_2() {
const TEST_DATA: &str = r#"
{
"639-2": [
{
"alpha_2": "gd",
"alpha_3": "gla",
"name": "Gaelic; Scottish Gaelic"
},
{
"alpha_2": "ga",
"alpha_3": "gle",
"name": "Irish"
},
{
"alpha_2": "gl",
"alpha_3": "glg",
"name": "Galician"
}
]
impl From<&Entry<'_>> for Language {
fn from(value: &Entry<'_>) -> Self {
let display = if let Some(name) = value.common_name {
name.into()
} else {
value.name.into()
};
Self {
code: value.code.into(),
code2: value.code2.map(|v| v.into()),
display_name: display,
inverted_name: value.inverted_name.map(|v| v.into()),
}
"#;

let loaded = serde_json::from_str::<DocumentTwoCode>(TEST_DATA).expect("Failed to decode ISO-639 2-code data");
let ga = loaded
.entries
.iter()
.find(|i| i.code3 == "gle")
.expect("Failed to find GLE");
assert_eq!(ga.name, "Irish");
}
}

#[cfg(test)]
mod tests {
use super::{Document, Kind, Scope};

#[test]
fn load_3() {
fn load_iso_639_3() {
const TEST_DATA: &str = r#"
{
"639-3": [
Expand Down Expand Up @@ -170,8 +126,7 @@ mod tests {
}
"#;

let loaded =
serde_json::from_str::<DocumentThreeCode>(TEST_DATA).expect("Failed to decode ISO-639 3-code data");
let loaded = serde_json::from_str::<Document>(TEST_DATA).expect("Failed to decode ISO-639-3 data");
let ga = loaded
.entries
.iter()
Expand Down
40 changes: 39 additions & 1 deletion src/system/locale/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,45 @@
//
// SPDX-License-Identifier: MPL-2.0

use std::fmt;

use thiserror::Error;

/// Locale joins Territory + Language
#[derive(Debug)]
pub struct Locale<'a> {
pub name: String,
pub display_name: String,
pub language: &'a Language,
pub territory: &'a Territory,
pub modifier: Option<String>,
pub codeset: Option<String>,
}

impl fmt::Display for Locale<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.display_name)
}
}

/// Sane representation for UI purposes
#[derive(PartialEq, Eq, Debug)]
pub struct Territory {
pub code: String,
pub code2: String,
pub display_name: String,
pub flag: String,
}

/// Simplistic language representation
#[derive(PartialEq, Eq, Debug)]
pub struct Language {
pub code: String,
pub code2: Option<String>,
pub display_name: String,
pub inverted_name: Option<String>,
}

#[derive(Debug, Error)]
pub enum Error {
#[error("io: {0}")]
Expand All @@ -14,6 +51,7 @@ pub enum Error {
}

mod iso_3166;
mod iso_639;
mod iso_639_2;
mod iso_639_3;

mod registry;
Loading

0 comments on commit b91a7c1

Please sign in to comment.