diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2025-06-06 23:55:23 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2025-06-07 00:00:39 +0200 |
| commit | ad893a4fb44244132d710d7f94fc99a7d83f1b87 (patch) | |
| tree | b567690b5388de7919b6422e17b4637d3a323477 /server/common | |
| parent | f58f6b91e851897444186e9291804fc9b58bbd60 (diff) | |
grit: Add method for generating message translation id
reimplemented from a description of the grit id calculation
Diffstat (limited to 'server/common')
| -rw-r--r-- | server/common/Cargo.toml | 1 | ||||
| -rw-r--r-- | server/common/src/grit.rs | 33 | ||||
| -rw-r--r-- | server/common/src/tests.rs | 120 |
3 files changed, 154 insertions, 0 deletions
diff --git a/server/common/Cargo.toml b/server/common/Cargo.toml index 25d3d39..2c70d43 100644 --- a/server/common/Cargo.toml +++ b/server/common/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" anyhow.workspace = true futures.workspace = true log.workspace = true +md5 = "0.7.0" pathdiff = "0.2.3" serde.workspace = true tokio = { workspace = true, features = ["fs", "macros", "process", "rt", "sync"] } diff --git a/server/common/src/grit.rs b/server/common/src/grit.rs index dbf4f89..a510724 100644 --- a/server/common/src/grit.rs +++ b/server/common/src/grit.rs @@ -1156,3 +1156,36 @@ pub async fn parse_grit_with_parts(path: impl AsRef<Path>) -> anyhow::Result<Gri expand_messages(&mut grit.release.messages.messages, path).await?; Ok(grit) } + +fn get_presentable_content(message: &Message) -> String { + let mut ret = String::new(); + for c in &message.content { + match c { + TextPlaceholder::Text(value) => ret += value.as_str(), + TextPlaceholder::Placeholder { + name, + content: _, + example: _, + } => ret += name.as_str(), + } + } + ret +} + +fn fingerprint(value: &str) -> i64 { + u64::from_be_bytes(md5::compute(value).0[0..8].try_into().unwrap()).cast_signed() +} + +pub fn get_message_id(message: &Message) -> i64 { + let mut message_id = fingerprint(get_presentable_content(message).as_str()); + if let Some(meaning) = &message.meaning { + let meaning_id = fingerprint(meaning.as_str()); + if message_id < 0 { + message_id = (message_id << 1) + meaning_id + 1 + } else { + message_id = (message_id << 1) + meaning_id + } + } + // Avoid returning negative ids + message_id & 0x7fffffffffffffff +} diff --git a/server/common/src/tests.rs b/server/common/src/tests.rs index 2b6aae5..9ce44c8 100644 --- a/server/common/src/tests.rs +++ b/server/common/src/tests.rs @@ -688,3 +688,123 @@ async fn test_grit_parse_include_parts() { }, ) } + +#[test] +fn test_grit_get_message_id() { + assert_eq!( + grit::get_message_id(&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()),], + },), + 8820817407110198400, + ); + assert_eq!( + grit::get_message_id(&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()), + }, + ], + },), + 8443102241046796905, + ); + assert_eq!( + grit::get_message_id(&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(),), + ], + },), + 2466140279568640908, + ); + assert_eq!( + grit::get_message_id( + &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(), + ), + ], + }, + ), + 7770247413830876286, + ) +} |
