es_fluent_shared/resource/
keys.rs1use crate::fluent::FluentDomain;
2use crate::namespace::{NamespacePathError, ResolvedNamespace};
3use crate::registry::StaticFluentDomain;
4
5#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
7#[error("{0}")]
8pub struct ResourceKeyError(#[from] pub(super) NamespacePathError);
9
10#[derive(
16 Clone, Debug, derive_more::AsRef, derive_more::Display, Eq, Hash, Ord, PartialEq, PartialOrd,
17)]
18#[as_ref(str)]
19pub struct ResourceKey(String);
20
21impl ResourceKey {
22 pub fn try_new(key: impl Into<String>) -> Result<Self, ResourceKeyError> {
24 let key = key.into();
25 crate::namespace::validate_namespace_path_typed(&key)?;
26 Ok(Self(key))
27 }
28
29 #[allow(
31 clippy::panic,
32 reason = "static metadata uses literal keys; use try_new for dynamic input"
33 )]
34 pub fn from_static_path(key: &'static str) -> Self {
35 Self::try_new(key)
36 .unwrap_or_else(|error| panic!("invalid static resource key '{key}': {error}"))
37 }
38
39 pub fn from_static_domain(domain: StaticFluentDomain) -> Self {
41 Self(domain.as_str().to_string())
42 }
43
44 pub fn from_static_domain_and_namespace(
46 domain: StaticFluentDomain,
47 namespace: &ResolvedNamespace,
48 ) -> Self {
49 Self(format!("{}/{namespace}", domain.as_str()))
50 }
51
52 pub(super) fn from_domain(domain: &FluentDomain) -> Self {
53 Self(domain.as_str().to_string())
54 }
55
56 pub(super) fn from_domain_and_namespace(
57 domain: &FluentDomain,
58 namespace: &ResolvedNamespace,
59 ) -> Self {
60 Self(format!("{}/{namespace}", domain.as_str()))
61 }
62
63 pub fn as_str(&self) -> &str {
65 &self.0
66 }
67
68 pub fn domain(&self) -> &str {
70 self.0.split('/').next().unwrap_or(self.as_str())
71 }
72
73 pub fn domain_name(&self) -> FluentDomain {
75 FluentDomain::try_new(self.domain())
76 .expect("resource key validation should guarantee a valid domain segment")
77 }
78}
79
80impl serde::Serialize for ResourceKey {
81 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
82 where
83 S: serde::Serializer,
84 {
85 serializer.serialize_str(self.as_str())
86 }
87}
88
89impl<'de> serde::Deserialize<'de> for ResourceKey {
90 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91 where
92 D: serde::Deserializer<'de>,
93 {
94 let value = <String as serde::Deserialize>::deserialize(deserializer)?;
95 Self::try_new(value).map_err(serde::de::Error::custom)
96 }
97}