summaryrefslogtreecommitdiff
path: root/server/common
diff options
context:
space:
mode:
Diffstat (limited to 'server/common')
-rw-r--r--server/common/Cargo.toml1
-rw-r--r--server/common/src/grit.rs33
-rw-r--r--server/common/src/tests.rs120
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,
+ )
+}