es_fluent_shared/resource/
spec.rs1use crate::LanguageIdentifier;
2use crate::fluent::FluentDomain;
3use crate::namespace::ResolvedNamespace;
4use crate::registry::StaticFluentDomain;
5
6use super::{LocaleRelativeFtlPath, ResourceKey, ResourcePlanError};
7
8#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize)]
10pub struct ModuleResourceSpec {
11 pub key: ResourceKey,
13 pub locale_relative_path: LocaleRelativeFtlPath,
15 pub required: bool,
17}
18
19impl ModuleResourceSpec {
20 pub fn try_new(
22 key: impl Into<String>,
23 locale_relative_path: impl Into<String>,
24 required: bool,
25 ) -> Result<Self, ResourcePlanError> {
26 let key = key.into();
27 let locale_relative_path = locale_relative_path.into();
28 Ok(Self {
29 key: ResourceKey::try_new(key.clone())
30 .map_err(|details| ResourcePlanError::InvalidResourceKey { key, details })?,
31 locale_relative_path: LocaleRelativeFtlPath::try_new(locale_relative_path.clone())
32 .map_err(|details| ResourcePlanError::InvalidResourcePath {
33 path: locale_relative_path,
34 details,
35 })?,
36 required,
37 })
38 }
39
40 pub fn new(
42 key: ResourceKey,
43 locale_relative_path: LocaleRelativeFtlPath,
44 required: bool,
45 ) -> Self {
46 Self {
47 key,
48 locale_relative_path,
49 required,
50 }
51 }
52
53 pub fn try_base(domain: &str, required: bool) -> Result<Self, ResourcePlanError> {
55 Self::try_new(domain, format!("{domain}.ftl"), required)
56 }
57
58 pub fn base(domain: &str, required: bool) -> Self {
60 let domain =
61 FluentDomain::try_new(domain).expect("base resource domain should be validated");
62 Self::base_for_domain(&domain, required)
63 }
64
65 pub fn base_for_static_domain(domain: StaticFluentDomain, required: bool) -> Self {
67 Self::new(
68 ResourceKey::from_static_domain(domain),
69 LocaleRelativeFtlPath::try_new(format!("{}.ftl", domain.as_str()))
70 .expect("static domain should produce a valid locale-relative FTL path"),
71 required,
72 )
73 }
74
75 pub(super) fn base_for_domain(domain: &FluentDomain, required: bool) -> Self {
76 Self::new(
77 ResourceKey::from_domain(domain),
78 LocaleRelativeFtlPath::try_new(format!("{}.ftl", domain.as_str()))
79 .expect("domain should produce a valid locale-relative FTL path"),
80 required,
81 )
82 }
83
84 pub fn try_namespaced(
86 domain: &str,
87 namespace: &ResolvedNamespace,
88 required: bool,
89 ) -> Result<Self, ResourcePlanError> {
90 Self::try_new(
91 format!("{domain}/{namespace}"),
92 format!("{domain}/{namespace}.ftl"),
93 required,
94 )
95 }
96
97 pub fn namespaced(domain: &str, namespace: &ResolvedNamespace, required: bool) -> Self {
99 let domain =
100 FluentDomain::try_new(domain).expect("namespaced resource domain should be validated");
101 Self::namespaced_for_domain(&domain, namespace, required)
102 }
103
104 pub fn namespaced_for_static_domain(
106 domain: StaticFluentDomain,
107 namespace: &ResolvedNamespace,
108 required: bool,
109 ) -> Self {
110 Self::new(
111 ResourceKey::from_static_domain_and_namespace(domain, namespace),
112 LocaleRelativeFtlPath::try_new(format!("{}/{namespace}.ftl", domain.as_str())).expect(
113 "static domain and namespace should produce a valid locale-relative FTL path",
114 ),
115 required,
116 )
117 }
118
119 pub(super) fn namespaced_for_domain(
120 domain: &FluentDomain,
121 namespace: &ResolvedNamespace,
122 required: bool,
123 ) -> Self {
124 Self::new(
125 ResourceKey::from_domain_and_namespace(domain, namespace),
126 LocaleRelativeFtlPath::try_new(format!("{}/{namespace}.ftl", domain.as_str()))
127 .expect("domain and namespace should produce a valid locale-relative FTL path"),
128 required,
129 )
130 }
131
132 pub fn locale_path(&self, lang: &LanguageIdentifier) -> String {
134 format!("{}/{}", lang, self.locale_relative_path)
135 }
136}