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
65/// Reflects `types::SearchEngineUrls`, but using `EngineUrl`.
66#[derive(Debug, uniffi::Record, PartialEq, Deserialize, Clone, Default)]
67#[serde(rename_all = "camelCase")]
68pub(crate) struct JSONEngineUrls {
69    /// The URL to use for searches.
70    pub search: Option<JSONEngineUrl>,
71
72    /// The URL to use for suggestions.
73    pub suggestions: Option<JSONEngineUrl>,
74
75    /// The URL to use for trending suggestions.
76    pub trending: Option<JSONEngineUrl>,
77
78    /// The URL of the search engine homepage.
79    pub search_form: Option<JSONEngineUrl>,
80
81    /// The URL to use for visual searches.
82    pub visual_search: Option<JSONEngineUrl>,
83}
84
85/// Represents the engine base section of the configuration.
86#[derive(Debug, Default, Deserialize, Clone)]
87#[serde(rename_all = "camelCase")]
88pub(crate) struct JSONEngineBase {
89    /// A list of aliases for this engine.
90    pub aliases: Option<Vec<String>>,
91
92    /// The character set this engine uses for queries. Defaults to 'UTF=8' if not set.
93    pub charset: Option<String>,
94
95    /// The classification of search engine according to the main search types
96    /// (e.g. general, shopping, travel, dictionary). Currently, only marking as
97    /// a general search engine is supported.
98    #[serde(default)]
99    pub classification: SearchEngineClassification,
100
101    /// The user visible name for the search engine.
102    pub name: String,
103
104    /// The partner code for the engine. This will be inserted into parameters
105    /// which include `{partnerCode}`.
106    pub partner_code: Option<String>,
107
108    /// The URLs associated with the search engine.
109    pub urls: JSONEngineUrls,
110}
111
112/// Specifies details of possible user environments that the engine or variant
113/// applies to.
114#[derive(Debug, Deserialize, Clone, Default)]
115#[serde(rename_all = "camelCase")]
116pub(crate) struct JSONVariantEnvironment {
117    /// Indicates that this section applies to all regions and locales. May be
118    /// modified by excluded_regions/excluded_locales.
119    #[serde(default)]
120    pub all_regions_and_locales: bool,
121
122    /// A vector of locales that this section should be excluded from. 'default'
123    /// will apply to situations where we have not been able to detect the user's
124    /// locale.
125    #[serde(default)]
126    pub excluded_locales: Vec<String>,
127
128    /// A vector of regions that this section should be excluded from. 'default'
129    /// will apply to situations where we have not been able to detect the user's
130    /// region.
131    #[serde(default)]
132    pub excluded_regions: Vec<String>,
133
134    /// A vector of locales that this section applies to. 'default' will apply
135    /// to situations where we have not been able to detect the user's locale.
136    #[serde(default)]
137    pub locales: Vec<String>,
138
139    /// A vector of regions that this section applies to. 'default' will apply
140    /// to situations where we have not been able to detect the user's region.
141    #[serde(default)]
142    pub regions: Vec<String>,
143
144    /// A vector of distribution identifiers that this section applies to.
145    #[serde(default)]
146    pub distributions: Vec<String>,
147
148    /// A vector of distributions that this section should be excluded from.
149    #[serde(default)]
150    pub excluded_distributions: Vec<String>,
151
152    /// A vector of applications that this applies to.
153    #[serde(default)]
154    pub applications: Vec<SearchApplicationName>,
155
156    /// A vector of release channels that this section applies to (not set = everywhere).
157    #[serde(default)]
158    pub channels: Vec<SearchUpdateChannel>,
159
160    /// The experiment that this section applies to.
161    #[serde(default)]
162    pub experiment: String,
163
164    /// The minimum application version this section applies to.
165    #[serde(default)]
166    pub min_version: String,
167
168    /// The maximum application version this section applies to.
169    #[serde(default)]
170    pub max_version: String,
171
172    #[serde(default)]
173    pub device_type: Vec<SearchDeviceType>,
174}
175
176/// Describes an individual variant of a search engine.
177#[derive(Debug, Deserialize, Clone)]
178#[serde(rename_all = "camelCase")]
179pub(crate) struct JSONEngineVariant {
180    /// Details of the possible user environments that this variant applies to.
181    pub environment: JSONVariantEnvironment,
182
183    /// Indicates the date until which the engine variant or subvariant is considered new
184    /// (format: YYYY-MM-DD).
185    pub is_new_until: Option<String>,
186
187    /// This search engine is presented as an option that the user may enable.
188    /// If not specified, defaults to false.
189    #[serde(default)]
190    pub optional: bool,
191
192    /// The partner code for the engine or variant. This will be inserted into
193    /// parameters which include '{partnerCode}'
194    pub partner_code: Option<String>,
195
196    /// Suffix that is appended to the search engine identifier following a dash,
197    /// i.e. `<identifier>-<suffix>`. There should always be a suffix supplied
198    /// if the partner code is different for a reason other than being on a
199    /// different platform.
200    pub telemetry_suffix: Option<String>,
201
202    /// The urls for this variant.
203    pub urls: Option<JSONEngineUrls>,
204
205    /// This section describes subvariations of this search engine that may occur
206    /// depending on the user's environment. The last subvariant that matches
207    /// the user's environment will be applied to the engine.
208    ///
209    /// Note: sub-variants are only supported in a top-level variant. You cannot
210    /// have nested sub-variants.
211    #[serde(default)]
212    pub sub_variants: Vec<JSONEngineVariant>,
213}
214
215/// Represents an individual engine record in the configuration.
216#[derive(Debug, Deserialize, Clone)]
217#[serde(rename_all = "camelCase")]
218pub(crate) struct JSONEngineRecord {
219    /// The identiifer for the search engine.
220    pub identifier: String,
221
222    /// The base information of the search engine, may be extended by the
223    /// variants.
224    pub base: JSONEngineBase,
225
226    /// Describes variations of this search engine that may occur depending on
227    /// the user's environment. The last variant that matches the user's
228    /// environment will be applied to the engine, subvariants may also be applied.
229    pub variants: Vec<JSONEngineVariant>,
230}
231
232#[derive(Debug, Deserialize, Clone)]
233#[serde(rename_all = "camelCase")]
234pub(crate) struct JSONSpecificDefaultRecord {
235    /// The identifier of the engine that will be used as the application default
236    /// for the associated environment. If the entry is suffixed with a star,
237    /// matching is applied on a "starts with" basis.
238    #[serde(default)]
239    pub default: String,
240
241    /// The identifier of the engine that will be used as the application default
242    /// in private mode for the associated environment. If the entry is suffixed
243    /// with a star, matching is applied on a "starts with" basis.
244    #[serde(default)]
245    pub default_private: String,
246
247    /// The specific environment to match for this record.
248    pub environment: JSONVariantEnvironment,
249}
250
251/// Represents the default engines record.
252#[derive(Debug, Deserialize, Clone)]
253#[serde(rename_all = "camelCase")]
254pub(crate) struct JSONDefaultEnginesRecord {
255    /// The identifier of the engine that will be used as the application default
256    /// if no other engines are specified as default.
257    pub global_default: String,
258
259    /// The identifier of the engine that will be used as the application default
260    /// in private mode if no other engines are specified as default.
261    #[serde(default)]
262    pub global_default_private: String,
263
264    /// The specific environment filters to set a different default engine. The
265    /// array is ordered, when multiple entries match on environments, the later
266    /// entry will override earlier entries.
267    #[serde(default)]
268    pub specific_defaults: Vec<JSONSpecificDefaultRecord>,
269}
270
271#[derive(Debug, Deserialize, Clone)]
272#[serde(rename_all = "camelCase")]
273pub(crate) struct JSONEngineOrder {
274    /// The specific environment to match for this record.
275    pub environment: JSONVariantEnvironment,
276
277    /// The order of engine identifiers for the associated environment. If engines
278    /// are present for the user but not included in this list, they will follow
279    /// after the ones in this list in alphabetical order. If an individual entry
280    /// is suffixed with a star, matching is applied on a "starts with" basis.
281    #[serde(default)]
282    pub order: Vec<String>,
283}
284
285/// Represents the engine orders record.
286#[derive(Debug, Deserialize, Clone)]
287#[serde(rename_all = "camelCase")]
288pub(crate) struct JSONEngineOrdersRecord {
289    /// When a user's instance matches the defined environments, the associated
290    /// engine order will be applied. The array is ordered, when multiple entries
291    /// match on environments, the later entry will override earlier entries.
292    pub orders: Vec<JSONEngineOrder>,
293}
294
295/// Represents the available locales record.
296#[derive(Debug, Deserialize, Clone)]
297#[serde(rename_all = "camelCase")]
298pub(crate) struct JSONAvailableLocalesRecord {
299    /// The available locales in the search config v2.
300    pub locales: Vec<String>,
301}
302
303/// Represents an individual record in the raw search configuration.
304#[derive(Debug, Deserialize, Clone)]
305#[serde(tag = "recordType", rename_all = "camelCase")]
306pub(crate) enum JSONSearchConfigurationRecords {
307    DefaultEngines(JSONDefaultEnginesRecord),
308    Engine(Box<JSONEngineRecord>),
309    EngineOrders(JSONEngineOrdersRecord),
310    AvailableLocales(JSONAvailableLocalesRecord),
311    // Include some flexibilty if we choose to add new record types in future.
312    // Current versions of the application receiving the configuration will
313    // ignore the new record types.
314    #[serde(other)]
315    Unknown,
316}
317
318/// Represents the search configuration as received from remote settings.
319#[derive(Debug, Deserialize)]
320pub(crate) struct JSONSearchConfiguration {
321    pub data: Vec<JSONSearchConfigurationRecords>,
322}