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;