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}