search/
configuration_types.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5//! This module defines the structures that we use for serde_json to parse
6//! the search configuration.
7
8use crate::{
9    SearchApplicationName, SearchDeviceType, SearchEngineClassification, SearchUpdateChannel,
10    SearchUrlParam,
11};
12use serde::Deserialize;
13
14/// The list of possible submission methods for search engine urls.
15#[derive(Debug, uniffi::Enum, PartialEq, Deserialize, Clone, Default)]
16#[serde(rename_all = "UPPERCASE")]
17pub(crate) enum JSONEngineMethod {
18    Post = 2,
19    #[serde(other)]
20    #[default]
21    Get = 1,
22}
23
24impl JSONEngineMethod {
25    pub fn as_str(&self) -> &'static str {
26        match self {
27            JSONEngineMethod::Get => "GET",
28            JSONEngineMethod::Post => "POST",
29        }
30    }
31}
32
33/// Defines an individual search engine URL. This is defined separately to
34/// `types::SearchEngineUrl` as various fields may be optional in the supplied
35/// configuration.
36#[derive(Debug, uniffi::Record, PartialEq, Deserialize, Clone, Default)]
37#[serde(rename_all = "camelCase")]
38pub(crate) struct JSONEngineUrl {
39    /// The PrePath and FilePath of the URL. May include variables for engines
40    /// which have a variable FilePath, e.g. `{searchTerms}` for when a search
41    /// term is within the path of the url.
42    pub base: Option<String>,
43
44    /// The HTTP method to use to send the request (`GET` or `POST`).
45    /// If the engine definition has not specified the method, it defaults to GET.
46    pub method: Option<JSONEngineMethod>,
47
48    /// The parameters for this URL.
49    pub params: Option<Vec<SearchUrlParam>>,
50
51    /// The name of the query parameter for the search term. Automatically
52    /// appended to the end of the query. This may be skipped if `{searchTerms}`
53    /// is included in the base.
54    pub search_term_param_name: Option<String>,
55}
56
57/// Reflects `types::SearchEngineUrls`, but using `EngineUrl`.
58#[derive(Debug, uniffi::Record, PartialEq, Deserialize, Clone, Default)]
59#[serde(rename_all = "camelCase")]
60pub(crate) struct JSONEngineUrls {
61    /// The URL to use for searches.
62    pub search: Option<JSONEngineUrl>,
63
64    /// The URL to use for suggestions.
65    pub suggestions: Option<JSONEngineUrl>,
66
67    /// The URL to use for trending suggestions.
68    pub trending: Option<JSONEngineUrl>,
69
70    /// The URL of the search engine homepage.
71    pub search_form: Option<JSONEngineUrl>,
72}
73
74/// Represents the engine base section of the configuration.
75#[derive(Debug, Default, Deserialize, Clone)]
76#[serde(rename_all = "camelCase")]
77pub(crate) struct JSONEngineBase {
78    /// A list of aliases for this engine.
79    pub aliases: Option<Vec<String>>,
80
81    /// The character set this engine uses for queries. Defaults to 'UTF=8' if not set.
82    pub charset: Option<String>,
83
84    /// The classification of search engine according to the main search types
85    /// (e.g. general, shopping, travel, dictionary). Currently, only marking as
86    /// a general search engine is supported.
87    #[serde(default)]
88    pub classification: SearchEngineClassification,
89
90    /// The user visible name for the search engine.
91    pub name: String,
92
93    /// The partner code for the engine. This will be inserted into parameters
94    /// which include `{partnerCode}`.
95    pub partner_code: Option<String>,
96
97    /// The URLs associated with the search engine.
98    pub urls: JSONEngineUrls,
99}
100
101/// Specifies details of possible user environments that the engine or variant
102/// applies to.
103#[derive(Debug, Deserialize, Clone, Default)]
104#[serde(rename_all = "camelCase")]
105pub(crate) struct JSONVariantEnvironment {
106    /// Indicates that this section applies to all regions and locales. May be
107    /// modified by excluded_regions/excluded_locales.
108    #[serde(default)]
109    pub all_regions_and_locales: bool,
110
111    /// A vector of locales that this section should be excluded from. 'default'
112    /// will apply to situations where we have not been able to detect the user's
113    /// locale.
114    #[serde(default)]
115    pub excluded_locales: Vec<String>,
116
117    /// A vector of regions that this section should be excluded from. 'default'
118    /// will apply to situations where we have not been able to detect the user's
119    /// region.
120    #[serde(default)]
121    pub excluded_regions: Vec<String>,
122
123    /// A vector of locales that this section applies to. 'default' will apply
124    /// to situations where we have not been able to detect the user's locale.
125    #[serde(default)]
126    pub locales: Vec<String>,
127
128    /// A vector of regions that this section applies to. 'default' will apply
129    /// to situations where we have not been able to detect the user's region.
130    #[serde(default)]
131    pub regions: Vec<String>,
132
133    /// A vector of distribution identifiers that this section applies to.
134    #[serde(default)]
135    pub distributions: Vec<String>,
136
137    /// A vector of distributions that this section should be excluded from.
138    #[serde(default)]
139    pub excluded_distributions: Vec<String>,
140
141    /// A vector of applications that this applies to.
142    #[serde(default)]
143    pub applications: Vec<SearchApplicationName>,
144
145    /// A vector of release channels that this section applies to (not set = everywhere).
146    #[serde(default)]
147    pub channels: Vec<SearchUpdateChannel>,
148
149    /// The experiment that this section applies to.
150    #[serde(default)]
151    pub experiment: String,
152
153    /// The minimum application version this section applies to.
154    #[serde(default)]
155    pub min_version: String,
156
157    /// The maximum application version this section applies to.
158    #[serde(default)]
159    pub max_version: String,
160
161    #[serde(default)]
162    pub device_type: Vec<SearchDeviceType>,
163}
164
165/// Describes an individual variant of a search engine.
166#[derive(Debug, Deserialize, Clone)]
167#[serde(rename_all = "camelCase")]
168pub(crate) struct JSONEngineVariant {
169    /// Details of the possible user environments that this variant applies to.
170    pub environment: JSONVariantEnvironment,
171
172    /// Indicates the date until which the engine variant or subvariant is considered new
173    /// (format: YYYY-MM-DD).
174    pub is_new_until: Option<String>,
175
176    /// This search engine is presented as an option that the user may enable.
177    /// If not specified, defaults to false.
178    #[serde(default)]
179    pub optional: bool,
180
181    /// The partner code for the engine or variant. This will be inserted into
182    /// parameters which include '{partnerCode}'
183    pub partner_code: Option<String>,
184
185    /// Suffix that is appended to the search engine identifier following a dash,
186    /// i.e. `<identifier>-<suffix>`. There should always be a suffix supplied
187    /// if the partner code is different for a reason other than being on a
188    /// different platform.
189    pub telemetry_suffix: Option<String>,
190
191    /// The urls for this variant.
192    pub urls: Option<JSONEngineUrls>,
193
194    /// This section describes subvariations of this search engine that may occur
195    /// depending on the user's environment. The last subvariant that matches
196    /// the user's environment will be applied to the engine.
197    ///
198    /// Note: sub-variants are only supported in a top-level variant. You cannot
199    /// have nested sub-variants.
200    #[serde(default)]
201    pub sub_variants: Vec<JSONEngineVariant>,
202}
203
204/// Represents an individual engine record in the configuration.
205#[derive(Debug, Deserialize, Clone)]
206#[serde(rename_all = "camelCase")]
207pub(crate) struct JSONEngineRecord {
208    /// The identiifer for the search engine.
209    pub identifier: String,
210
211    /// The base information of the search engine, may be extended by the
212    /// variants.
213    pub base: JSONEngineBase,
214
215    /// Describes variations of this search engine that may occur depending on
216    /// the user's environment. The last variant that matches the user's
217    /// environment will be applied to the engine, subvariants may also be applied.
218    pub variants: Vec<JSONEngineVariant>,
219}
220
221#[derive(Debug, Deserialize, Clone)]
222#[serde(rename_all = "camelCase")]
223pub(crate) struct JSONSpecificDefaultRecord {
224    /// The identifier of the engine that will be used as the application default
225    /// for the associated environment. If the entry is suffixed with a star,
226    /// matching is applied on a "starts with" basis.
227    #[serde(default)]
228    pub default: String,
229
230    /// The identifier of the engine that will be used as the application default
231    /// in private mode for the associated environment. If the entry is suffixed
232    /// with a star, matching is applied on a "starts with" basis.
233    #[serde(default)]
234    pub default_private: String,
235
236    /// The specific environment to match for this record.
237    pub environment: JSONVariantEnvironment,
238}
239
240/// Represents the default engines record.
241#[derive(Debug, Deserialize, Clone)]
242#[serde(rename_all = "camelCase")]
243pub(crate) struct JSONDefaultEnginesRecord {
244    /// The identifier of the engine that will be used as the application default
245    /// if no other engines are specified as default.
246    pub global_default: String,
247
248    /// The identifier of the engine that will be used as the application default
249    /// in private mode if no other engines are specified as default.
250    #[serde(default)]
251    pub global_default_private: String,
252
253    /// The specific environment filters to set a different default engine. The
254    /// array is ordered, when multiple entries match on environments, the later
255    /// entry will override earlier entries.
256    #[serde(default)]
257    pub specific_defaults: Vec<JSONSpecificDefaultRecord>,
258}
259
260#[derive(Debug, Deserialize, Clone)]
261#[serde(rename_all = "camelCase")]
262pub(crate) struct JSONEngineOrder {
263    /// The specific environment to match for this record.
264    pub environment: JSONVariantEnvironment,
265
266    /// The order of engine identifiers for the associated environment. If engines
267    /// are present for the user but not included in this list, they will follow
268    /// after the ones in this list in alphabetical order. If an individual entry
269    /// is suffixed with a star, matching is applied on a "starts with" basis.
270    #[serde(default)]
271    pub order: Vec<String>,
272}
273
274/// Represents the engine orders record.
275#[derive(Debug, Deserialize, Clone)]
276#[serde(rename_all = "camelCase")]
277pub(crate) struct JSONEngineOrdersRecord {
278    /// When a user's instance matches the defined environments, the associated
279    /// engine order will be applied. The array is ordered, when multiple entries
280    /// match on environments, the later entry will override earlier entries.
281    pub orders: Vec<JSONEngineOrder>,
282}
283
284/// Represents the available locales record.
285#[derive(Debug, Deserialize, Clone)]
286#[serde(rename_all = "camelCase")]
287pub(crate) struct JSONAvailableLocalesRecord {
288    /// The available locales in the search config v2.
289    pub locales: Vec<String>,
290}
291
292/// Represents an individual record in the raw search configuration.
293#[derive(Debug, Deserialize, Clone)]
294#[serde(tag = "recordType", rename_all = "camelCase")]
295pub(crate) enum JSONSearchConfigurationRecords {
296    DefaultEngines(JSONDefaultEnginesRecord),
297    Engine(Box<JSONEngineRecord>),
298    EngineOrders(JSONEngineOrdersRecord),
299    AvailableLocales(JSONAvailableLocalesRecord),
300    // Include some flexibilty if we choose to add new record types in future.
301    // Current versions of the application receiving the configuration will
302    // ignore the new record types.
303    #[serde(other)]
304    Unknown,
305}
306
307/// Represents the search configuration as received from remote settings.
308#[derive(Debug, Deserialize)]
309pub(crate) struct JSONSearchConfiguration {
310    pub data: Vec<JSONSearchConfigurationRecords>,
311}