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