ferrocat_po/api/
message_status.rs1use std::collections::BTreeSet;
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6use super::{CatalogMessage, CatalogMessageKey, EffectiveTranslationRef, NormalizedParsedCatalog};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
12#[non_exhaustive]
13pub enum CatalogMessageStatus {
14 Translated,
16 Missing,
18 Empty,
20 Obsolete,
22 Extra,
24}
25
26pub(super) fn active_message_keys(
27 catalog: &NormalizedParsedCatalog,
28) -> BTreeSet<CatalogMessageKey> {
29 catalog
30 .iter()
31 .filter_map(|(key, message)| (message.obsolete.is_none()).then_some(key.clone()))
32 .collect()
33}
34
35pub(super) fn classify_expected_message(
36 target_catalog: &NormalizedParsedCatalog,
37 key: &CatalogMessageKey,
38) -> CatalogMessageStatus {
39 let Some(message) = target_catalog.get(key) else {
40 return CatalogMessageStatus::Missing;
41 };
42 if message.obsolete.is_some() {
43 return CatalogMessageStatus::Obsolete;
44 }
45 if translation_is_empty(message) {
46 return CatalogMessageStatus::Empty;
47 }
48 CatalogMessageStatus::Translated
49}
50
51pub(super) fn is_extra_target_message(
52 source_keys: &BTreeSet<CatalogMessageKey>,
53 key: &CatalogMessageKey,
54 message: &CatalogMessage,
55) -> bool {
56 message.obsolete.is_none() && !source_keys.contains(key)
57}
58
59pub(super) fn translation_is_empty(message: &CatalogMessage) -> bool {
60 match message.effective_translation() {
61 EffectiveTranslationRef::Singular(value) => value.trim().is_empty(),
62 EffectiveTranslationRef::Plural(translations) => {
63 translations.is_empty() || translations.values().any(|value| value.trim().is_empty())
64 }
65 }
66}