fluent_fallback/
types.rs

1use fluent_bundle::FluentArgs;
2use std::borrow::Cow;
3
4#[derive(Debug)]
5pub struct L10nKey<'l> {
6    pub id: Cow<'l, str>,
7    pub args: Option<FluentArgs<'l>>,
8}
9
10impl<'l> From<&'l str> for L10nKey<'l> {
11    fn from(id: &'l str) -> Self {
12        Self {
13            id: id.into(),
14            args: None,
15        }
16    }
17}
18
19#[derive(Clone, Debug)]
20pub struct L10nAttribute<'l> {
21    pub name: Cow<'l, str>,
22    pub value: Cow<'l, str>,
23}
24
25#[derive(Clone, Debug)]
26pub struct L10nMessage<'l> {
27    pub value: Option<Cow<'l, str>>,
28    pub attributes: Vec<L10nAttribute<'l>>,
29}
30
31#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
32pub enum ResourceType {
33    /// This is a required resource.
34    ///
35    /// A bundle generator should not consider a solution as valid
36    /// if this resource is missing.
37    ///
38    /// This is the default when creating a [`ResourceId`].
39    Required,
40
41    /// This is an optional resource.
42    ///
43    /// A bundle generator should still populate a partial solution
44    /// even if this resource is missing.
45    ///
46    /// This is intended for experimental and/or under-development
47    /// resources that may not have content for all supported locales.
48    ///
49    /// This should be used sparingly, as it will greatly increase
50    /// the state space of the search for valid solutions which can
51    /// have a severe impact on performance.
52    Optional,
53}
54
55/// A resource identifier for a localization resource.
56#[derive(Clone, Debug)]
57pub struct ResourceId {
58    /// The resource identifier.
59    pub value: String,
60
61    /// The [`ResourceType`] for this resource.
62    ///
63    /// The default value (when converting from another type) is
64    /// [`ResourceType::Required`]. You should only set this to
65    /// [`ResourceType::Optional`] for experimental or under-development
66    /// features that may not yet have content in all eventually-supported locales.
67    ///
68    /// Setting this value to [`ResourceType::Optional`] for all resources
69    /// may have a severe impact on performance due to increasing the state space
70    /// of the solver.
71    pub resource_type: ResourceType,
72}
73
74impl ResourceId {
75    pub fn new<S: Into<String>>(value: S, resource_type: ResourceType) -> Self {
76        Self {
77            value: value.into(),
78            resource_type,
79        }
80    }
81
82    /// Returns [`true`] if the resource has [`ResourceType::Required`],
83    /// otherwise returns [`false`].
84    pub fn is_required(&self) -> bool {
85        matches!(self.resource_type, ResourceType::Required)
86    }
87
88    /// Returns [`true`] if the resource has [`ResourceType::Optional`],
89    /// otherwise returns [`false`].
90    pub fn is_optional(&self) -> bool {
91        matches!(self.resource_type, ResourceType::Optional)
92    }
93}
94
95impl<S: Into<String>> From<S> for ResourceId {
96    fn from(id: S) -> Self {
97        Self {
98            value: id.into(),
99            resource_type: ResourceType::Required,
100        }
101    }
102}
103
104impl std::fmt::Display for ResourceId {
105    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106        write!(f, "{}", self.value)
107    }
108}
109
110impl PartialEq<str> for ResourceId {
111    fn eq(&self, other: &str) -> bool {
112        self.value.as_str().eq(other)
113    }
114}
115
116impl Eq for ResourceId {}
117impl PartialEq for ResourceId {
118    fn eq(&self, other: &Self) -> bool {
119        self.value.eq(&other.value)
120    }
121}
122
123impl std::hash::Hash for ResourceId {
124    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
125        self.value.hash(state);
126    }
127}
128
129/// A trait for creating a [`ResourceId`] from another type.
130///
131/// This differs from the [`From`] trait in that the [`From`] trait
132/// always takes the default resource type of [`ResourceType::Required`].
133///
134/// If you need to create a resource with a non-default [`ResourceType`],
135/// such as [`ResourceType::Optional`], then use this trait.
136///
137/// This trait is automatically implemented for types that implement [`Into<String>`].
138pub trait ToResourceId {
139    /// Creates a [`ResourceId`] from [`self`], given a [`ResourceType`].
140    fn to_resource_id(self, resource_type: ResourceType) -> ResourceId;
141}
142
143impl<S: Into<String>> ToResourceId for S {
144    fn to_resource_id(self, resource_type: ResourceType) -> ResourceId {
145        ResourceId::new(self.into(), resource_type)
146    }
147}