Skip to main content

ferrocat_po/
api.rs

1mod catalog;
2mod compile;
3mod compile_types;
4mod file_io;
5mod helpers;
6mod ndjson;
7mod plural;
8mod types;
9
10pub use self::catalog::{parse_catalog, update_catalog, update_catalog_file};
11pub use self::compile::{
12    compile_catalog_artifact, compile_catalog_artifact_selected, compiled_key,
13};
14pub use self::compile_types::{
15    CompileCatalogArtifactOptions, CompileCatalogOptions, CompileSelectedCatalogArtifactOptions,
16    CompiledCatalog, CompiledCatalogArtifact, CompiledCatalogDiagnostic,
17    CompiledCatalogIdDescription, CompiledCatalogIdIndex, CompiledCatalogMissingMessage,
18    CompiledCatalogTranslationKind, CompiledCatalogUnavailableId, CompiledKeyStrategy,
19    CompiledMessage, CompiledTranslation, DescribeCompiledIdsReport,
20};
21pub use self::types::{
22    ApiError, CatalogMessage, CatalogMessageExtra, CatalogMessageKey, CatalogOrigin,
23    CatalogSemantics, CatalogStats, CatalogStorageFormat, CatalogUpdateInput, CatalogUpdateResult,
24    Diagnostic, DiagnosticSeverity, EffectiveTranslation, EffectiveTranslationRef,
25    ExtractedMessage, ExtractedPluralMessage, ExtractedSingularMessage, NormalizedParsedCatalog,
26    ObsoleteStrategy, OrderBy, ParseCatalogOptions, ParsedCatalog, PlaceholderCommentMode,
27    PluralEncoding, PluralSource, SourceExtractedMessage, TranslationShape,
28    UpdateCatalogFileOptions, UpdateCatalogOptions,
29};
30
31fn validate_source_locale(source_locale: &str) -> Result<(), ApiError> {
32    if source_locale.trim().is_empty() {
33        return Err(ApiError::InvalidArguments(
34            "source_locale must not be empty".to_owned(),
35        ));
36    }
37    Ok(())
38}
39
40fn validate_catalog_semantics(
41    semantics: CatalogSemantics,
42    storage_format: CatalogStorageFormat,
43    plural_encoding: PluralEncoding,
44) -> Result<(), ApiError> {
45    match semantics {
46        CatalogSemantics::IcuNative if plural_encoding != PluralEncoding::Icu => {
47            Err(ApiError::InvalidArguments(
48                "CatalogSemantics::IcuNative requires PluralEncoding::Icu".to_owned(),
49            ))
50        }
51        CatalogSemantics::GettextCompat if plural_encoding != PluralEncoding::Gettext => {
52            Err(ApiError::InvalidArguments(
53                "CatalogSemantics::GettextCompat requires PluralEncoding::Gettext".to_owned(),
54            ))
55        }
56        CatalogSemantics::GettextCompat if storage_format == CatalogStorageFormat::Ndjson => {
57            Err(ApiError::Unsupported(
58                "CatalogSemantics::GettextCompat is not supported for NDJSON catalogs".to_owned(),
59            ))
60        }
61        _ => Ok(()),
62    }
63}
64
65#[cfg(test)]
66mod unit_tests {
67    use super::{
68        ApiError, CatalogSemantics, CatalogStorageFormat, PluralEncoding,
69        validate_catalog_semantics, validate_source_locale,
70    };
71
72    #[test]
73    fn validate_source_locale_rejects_empty_values() {
74        assert!(validate_source_locale("en").is_ok());
75        assert!(validate_source_locale(" en ").is_ok());
76        assert!(matches!(
77            validate_source_locale(" \n\t "),
78            Err(ApiError::InvalidArguments(message)) if message.contains("must not be empty")
79        ));
80    }
81
82    #[test]
83    fn validate_catalog_semantics_accepts_only_supported_combinations() {
84        assert!(
85            validate_catalog_semantics(
86                CatalogSemantics::IcuNative,
87                CatalogStorageFormat::Po,
88                PluralEncoding::Icu
89            )
90            .is_ok()
91        );
92        assert!(
93            validate_catalog_semantics(
94                CatalogSemantics::IcuNative,
95                CatalogStorageFormat::Ndjson,
96                PluralEncoding::Icu
97            )
98            .is_ok()
99        );
100        assert!(
101            validate_catalog_semantics(
102                CatalogSemantics::GettextCompat,
103                CatalogStorageFormat::Po,
104                PluralEncoding::Gettext
105            )
106            .is_ok()
107        );
108
109        assert!(matches!(
110            validate_catalog_semantics(
111                CatalogSemantics::IcuNative,
112                CatalogStorageFormat::Po,
113                PluralEncoding::Gettext
114            ),
115            Err(ApiError::InvalidArguments(message))
116                if message.contains("IcuNative requires PluralEncoding::Icu")
117        ));
118        assert!(matches!(
119            validate_catalog_semantics(
120                CatalogSemantics::GettextCompat,
121                CatalogStorageFormat::Po,
122                PluralEncoding::Icu
123            ),
124            Err(ApiError::InvalidArguments(message))
125                if message.contains("GettextCompat requires PluralEncoding::Gettext")
126        ));
127        assert!(matches!(
128            validate_catalog_semantics(
129                CatalogSemantics::GettextCompat,
130                CatalogStorageFormat::Ndjson,
131                PluralEncoding::Gettext
132            ),
133            Err(ApiError::Unsupported(message))
134                if message.contains("not supported for NDJSON")
135        ));
136    }
137}
138
139#[cfg(test)]
140mod tests;