gistools/readers/gtfs/realtime/util.rs
1use alloc::{string::String, vec::Vec};
2use pbf::{ProtoRead, Protobuf};
3
4/// An internationalized message containing per-language versions of a snippet of
5/// text or a URL.
6/// One of the strings from a message will be picked up. The resolution proceeds
7/// as follows:
8/// 1. If the UI language matches the language code of a translation,
9/// the first matching translation is picked.
10/// 2. If a default UI language (e.g., English) matches the language code of a
11/// translation, the first matching translation is picked.
12/// 3. If some translation has an unspecified language code, that translation is
13/// picked.
14#[derive(Debug, Default, Clone, PartialEq)]
15pub struct GTFSRealtimeTranslatedString {
16 /// At least one translation must be provided.
17 pub translations: Vec<GTFSRealtimeTranslation>, // 1 [message]
18}
19impl GTFSRealtimeTranslatedString {
20 /// Converts the GTFSRealtimeTranslatedString to a String
21 pub fn to_string(&self, ui_language: Option<&str>) -> String {
22 if self.translations.is_empty() {
23 return String::new();
24 }
25 let ui_language = ui_language.unwrap_or("en");
26 self.translations
27 .iter()
28 .find(|t| t.language.as_ref().map(|l| l == ui_language).unwrap_or(false))
29 .map(|t| t.text.clone())
30 .unwrap_or_else(|| self.translations[0].text.clone())
31 }
32}
33/// Read in the contents of the GTFSRealtimeTranslatedString
34impl ProtoRead for GTFSRealtimeTranslatedString {
35 fn read(&mut self, tag: u64, pb: &mut Protobuf) {
36 match tag {
37 1 => {
38 let mut translation = GTFSRealtimeTranslation::default();
39 pb.read_message(&mut translation);
40 self.translations.push(translation);
41 }
42 _ => panic!("unknown tag {}", tag),
43 }
44 }
45}
46
47/// The translations field of a GTFSRealtimeTranslatedString
48#[derive(Debug, Default, Clone, PartialEq)]
49pub struct GTFSRealtimeTranslation {
50 /// A UTF-8 string containing the message.
51 pub text: String, // 1
52 /// BCP-47 language code. Can be omitted if the language is unknown or if
53 /// no i18n is done at all for the feed. At most one translation is
54 /// allowed to have an unspecified language tag.
55 pub language: Option<String>, // 2
56}
57/// Read in the contents of the GTFSRealtimeTranslation
58impl ProtoRead for GTFSRealtimeTranslation {
59 fn read(&mut self, tag: u64, pb: &mut Protobuf) {
60 match tag {
61 1 => self.text = pb.read_string(),
62 2 => self.language = Some(pb.read_string()),
63 _ => panic!("unknown tag {}", tag),
64 }
65 }
66}