url_cleaner_engine/tutorial/cleaner/control_flow/
maps.rs

1//! # [`Map`]
2//!
3//! [`Map`]s are key-value pairs with two extra properties:
4//!
5//! 1. The [`None`]/`null` key is written outside the map in the `"if_none"` field. This is because JSON doesn't let you use `null` as a key in a map.
6//!
7//! 2. Maps have a fallback value, called `else`, that is returned when using a key not otherwise in the map.
8//!
9//! Components that use maps "flatten" them, so while [`Action::PartMap`] contains an [`Action::PartMap::map`] field of type [`Map`], you would use it as follows:
10//!
11//! ```Json
12//! {"PartMap": {
13//!   "part": "NormalizedHost",
14//!   "map": {
15//!     "example.com": "The Action to take for example.com URLs",
16//!     "example2.com": "The Action to take for example2.com URLs"
17//!   },
18//!   "if_none": "Optional Action to take if the NormalizedHost is somehow None. This is usually useful for parts like {\"QueryParam\": \"abc\"} that can be expected to be None",
19//!   "else": "Optional Action to take if the Normalized Host is not in the map or if the NormalizedHost is None and the if_none field is absent"
20//! }}
21//! ```
22//!
23//! Maps excel at flattening certain long if-then-else chains. For example, take this [`Action`]:
24//!
25//! ```Json
26//! {"If": {
27//!   "if": {"PathIs": "/search"},
28//!   "then": "Do a thing",
29//!   "else": {"If": {
30//!     "if": {"PathStartsWith": "/user/"},
31//!     "then": "Do a different thing",
32//!     "else": {"If": {
33//!       "if": {"PathStartsWith": "/post/"},
34//!       "then": "Do yet another thing"
35//!     }}
36//!   }}
37//! }}
38//! ```
39//!
40//! While not every situation allows for this, the above example can be simplified dramatically by using [maps] and, in this case specifically, [`Action::PartMap`].
41//!
42//! ```Json
43//! {"PartMap": {
44//!   "part": {"PathSegment": 0},
45//!   "map": {
46//!     "search": "Do a thing",
47//!     "user": "Do a different thing",
48//!     "post": "Do yet another thing"
49//!   }
50//! }}
51//! ```
52//!
53//! While this is simpler and usually faster (It's a [`HashMap`]), the behavior has been changed slightly.
54//!
55//! 1. For the first branch, the scope of matching URLs was expanded from only URLs with a path of `/search` to also including URLs with paths like `/search/`, `/search/abc`, and so on.
56//!
57//! 2. For both the user and post branches, the change results in accepting not just paths of `/user/` and `/post/`, but paths of `/user` and `/post`.
58//!
59//! While most websites are unlikely to care about these changes (what website has both `/user/user1234` and `/user` as valid paths?), care should be taken to ensure these sorts of changes are relegated only to "invalid" URLs.
60
61pub(crate) use super::*;