summaryrefslogtreecommitdiffstats
path: root/third_party/rust/fluent-fallback/src/types.rs
blob: 6b87fa0522e628981ee66123afd01e7708d48cdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use fluent_bundle::FluentArgs;
use std::borrow::Cow;

#[derive(Debug)]
pub struct L10nKey<'l> {
    pub id: Cow<'l, str>,
    pub args: Option<FluentArgs<'l>>,
}

impl<'l> From<&'l str> for L10nKey<'l> {
    fn from(id: &'l str) -> Self {
        Self {
            id: id.into(),
            args: None,
        }
    }
}

#[derive(Debug, Clone)]
pub struct L10nAttribute<'l> {
    pub name: Cow<'l, str>,
    pub value: Cow<'l, str>,
}

#[derive(Debug, Clone)]
pub struct L10nMessage<'l> {
    pub value: Option<Cow<'l, str>>,
    pub attributes: Vec<L10nAttribute<'l>>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ResourceType {
    /// This is a required resource.
    ///
    /// A bundle generator should not consider a solution as valid
    /// if this resource is missing.
    ///
    /// This is the default when creating a [`ResourceId`].
    Required,

    /// This is an optional resource.
    ///
    /// A bundle generator should still populate a partial solution
    /// even if this resource is missing.
    ///
    /// This is intended for experimental and/or under-development
    /// resources that may not have content for all supported locales.
    ///
    /// This should be used sparingly, as it will greatly increase
    /// the state space of the search for valid solutions which can
    /// have a severe impact on performance.
    Optional,
}

/// A resource identifier for a localization resource.
#[derive(Debug, Clone, Hash)]
pub struct ResourceId {
    /// The resource identifier.
    pub value: String,

    /// The [`ResourceType`] for this resource.
    ///
    /// The default value (when converting from another type) is
    /// [`ResourceType::Required`]. You should only set this to
    /// [`ResourceType::Optional`] for experimental or under-development
    /// features that may not yet have content in all eventually-supported locales.
    ///
    /// Setting this value to [`ResourceType::Optional`] for all resources
    /// may have a severe impact on performance due to increasing the state space
    /// of the solver.
    pub resource_type: ResourceType,
}

impl ResourceId {
    pub fn new<S: Into<String>>(value: S, resource_type: ResourceType) -> Self {
        Self {
            value: value.into(),
            resource_type,
        }
    }

    /// Returns [`true`] if the resource has [`ResourceType::Required`],
    /// otherwise returns [`false`].
    pub fn is_required(&self) -> bool {
        matches!(self.resource_type, ResourceType::Required)
    }

    /// Returns [`true`] if the resource has [`ResourceType::Optional`],
    /// otherwise returns [`false`].
    pub fn is_optional(&self) -> bool {
        matches!(self.resource_type, ResourceType::Optional)
    }
}

impl<S: Into<String>> From<S> for ResourceId {
    fn from(id: S) -> Self {
        Self {
            value: id.into(),
            resource_type: ResourceType::Required,
        }
    }
}

impl std::fmt::Display for ResourceId {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.value)
    }
}

impl PartialEq<str> for ResourceId {
    fn eq(&self, other: &str) -> bool {
        self.value.as_str().eq(other)
    }
}

impl Eq for ResourceId {}
impl PartialEq for ResourceId {
    fn eq(&self, other: &Self) -> bool {
        self.value.eq(&other.value)
    }
}

/// A trait for creating a [`ResourceId`] from another type.
///
/// This differs from the [`From`] trait in that the [`From`] trait
/// always takes the default resource type of [`ResourceType::Required`].
///
/// If you need to create a resource with a non-default [`ResourceType`],
/// such as [`ResourceType::Optional`], then use this trait.
///
/// This trait is automatically implemented for types that implement [`Into<String>`].
pub trait ToResourceId {
    /// Creates a [`ResourceId`] from [`self`], given a [`ResourceType`].
    fn to_resource_id(self, resource_type: ResourceType) -> ResourceId;
}

impl<S: Into<String>> ToResourceId for S {
    fn to_resource_id(self, resource_type: ResourceType) -> ResourceId {
        ResourceId::new(self.into(), resource_type)
    }
}