diff options
| -rw-r--r-- | server/common/src/grit.rs | 58 | ||||
| -rw-r--r-- | server/common/src/tests.rs | 147 |
2 files changed, 205 insertions, 0 deletions
diff --git a/server/common/src/grit.rs b/server/common/src/grit.rs index fab1130..dbf4f89 100644 --- a/server/common/src/grit.rs +++ b/server/common/src/grit.rs @@ -1098,3 +1098,61 @@ pub async fn parse_grit_part(path: impl AsRef<Path>) -> anyhow::Result<GritPart> .await .unwrap() } + +fn if_message_to_if_message_part(messages: Vec<IfMessage>) -> Vec<IfMessagePart> { + messages + .into_iter() + .map(|x| match x { + IfMessage::Message(message) => IfMessagePart::Message(message), + IfMessage::If { expr, message } => IfMessagePart::If { + expr, + message: if_message_to_if_message_part(message), + }, + }) + .collect() +} + +async fn maybe_expand_message( + message: &mut IfMessagePart, + basepath: &Path, +) -> anyhow::Result<Vec<IfMessagePart>> { + match message { + IfMessagePart::Message(_) => Ok(Vec::new()), + IfMessagePart::Part(part) => { + let file_path = Path::new(part.file.as_str()); + let part_path = if let Some(parent) = basepath.parent() { + parent.join(file_path) + } else { + file_path.to_path_buf() + }; + let grit_part = parse_grit_part(part_path).await?; + Ok(if_message_to_if_message_part(grit_part.messages)) + } + IfMessagePart::If { expr: _, message } => { + Box::pin(expand_messages(message, basepath)).await?; + Ok(Vec::new()) + } + } +} + +async fn expand_messages(messages: &mut Vec<IfMessagePart>, basepath: &Path) -> anyhow::Result<()> { + let mut i = 0; + while i < messages.len() { + let new_messages = maybe_expand_message(&mut messages[i], basepath).await?; + if new_messages.is_empty() { + i += 1; + } else { + let j = new_messages.len(); + messages.splice(i..i + 1, new_messages); + i += j; + } + } + Ok(()) +} + +pub async fn parse_grit_with_parts(path: impl AsRef<Path>) -> anyhow::Result<Grit> { + let path = path.as_ref(); + let mut grit = parse_grit(path).await?; + expand_messages(&mut grit.release.messages.messages, path).await?; + Ok(grit) +} diff --git a/server/common/src/tests.rs b/server/common/src/tests.rs index c275c70..2b6aae5 100644 --- a/server/common/src/tests.rs +++ b/server/common/src/tests.rs @@ -541,3 +541,150 @@ async fn test_grit_parse_extra() { }, ) } + +#[tokio::test] +async fn test_grit_parse_include_parts() { + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/testdata/grit/base.grd"); + let grit = grit::parse_grit_with_parts(path).await.unwrap(); + assert_eq!( + grit.release.messages, + grit::Messages { + fallback_to_english: true, + messages: vec![ + grit::IfMessagePart::If { + expr: "pp_ifdef('include_extra')".to_string(), + message: vec![ + grit::IfMessagePart::Message( + grit::Message { + desc: "Extra title".to_string(), + name: "IDS_EXTRA".to_string(), + internal_comment: None, + meaning: None, + content: vec![ + grit::TextPlaceholder::Text("Extra title".to_string()), + ], + }, + ), + ], + }, + grit::IfMessagePart::Message( + grit::Message { + desc: "Title which is shown on the main bookmarks view.".to_string(), + name: "IDS_BOOKMARKS_FRAGMENT_TITLE".to_string(), + internal_comment: Some("section(bookmarks)".to_string()), + meaning: None, + content: vec![ + grit::TextPlaceholder::Text("Bookmarks".to_string()), + ], + }, + ), + grit::IfMessagePart::Message( + grit::Message { + desc: "Generic welcome string.".to_string(), + name: "IDS_GENERIC_WELCOME".to_string(), + internal_comment: Some("section(eula)".to_string()), + meaning: None, + content: vec![ + grit::TextPlaceholder::Text("Welcome to ".to_string()), + grit::TextPlaceholder::Placeholder { + name: "STRING".to_string(), + content: "%1$s".to_string(), + example: Some("Opera".to_string()), + }, + ], + }, + ), + grit::IfMessagePart::Message( + grit::Message { + desc: "First startup information about the license and privacy terms.".to_string(), + name: "IDS_START_TERMS".to_string(), + internal_comment: None, + meaning: None, + content: vec![ + grit::TextPlaceholder::Text( + "By using this application you are agreeing to Opera's ".to_string(), + ), + grit::TextPlaceholder::Placeholder { + name: "TOS_BEGIN".to_string(), + content: "<tos>".to_string(), + example: None, + }, + grit::TextPlaceholder::Text( + "Terms of Service".to_string(), + ), + grit::TextPlaceholder::Placeholder { + name: "TOS_END".to_string(), + content: "</tos>".to_string(), + example: None, + }, + grit::TextPlaceholder::Text( + ". Also, you can learn how Opera handles and protects your data in our ".to_string(), + ), + grit::TextPlaceholder::Placeholder { + name: "PRIVACY_BEGIN".to_string(), + content: "<privacy>".to_string(), + example: None, + }, + grit::TextPlaceholder::Text( + "Privacy Statement".to_string(), + ), + grit::TextPlaceholder::Placeholder { + name: "PRIVACY_END".to_string(), + content: "</privacy>".to_string(), + example: None, + }, + grit::TextPlaceholder::Text( + ".".to_string(), + ), + ], + }, + ), + grit::IfMessagePart::Message( + grit::Message { + desc: "Message which is shown when one or more folders have been deleted from the bookmark list.".to_string(), + name: "IDS_BOOKMARKS_FOLDERS_DELETED".to_string(), + internal_comment: None, + meaning: None, + content: vec![ + grit::TextPlaceholder::Text( + "{BOOKMARKS, plural,\n one {".to_string(), + ), + grit::TextPlaceholder::Placeholder { + name: "COUNT".to_string(), + content: "%1$d".to_string(), + example: Some("1".to_string()), + }, + grit::TextPlaceholder::Text( + " folder deleted}\n few {".to_string(), + ), + grit::TextPlaceholder::Placeholder { + name: "COUNT".to_string(), + content: "%1$d".to_string(), + example: Some("15".to_string()), + }, + grit::TextPlaceholder::Text( + " folders deleted}\n many {".to_string(), + ), + grit::TextPlaceholder::Placeholder { + name: "COUNT".to_string(), + content: "%1$d".to_string(), + example: Some("100".to_string()), + }, + grit::TextPlaceholder::Text( + " folders deleted}\n other {".to_string(), + ), + grit::TextPlaceholder::Placeholder { + name: "COUNT".to_string(), + content: "%1$d".to_string(), + example: Some("42".to_string()), + }, + grit::TextPlaceholder::Text( + " folders deleted}}".to_string(), + ), + ], + }, + ), + ], + }, + ) +} |
