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::*;