1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
// This file is part of caniuse-serde. It is subject to the license terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/caniuse-serde/master/COPYRIGHT. No part of caniuse-serde, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
// Copyright © 2017 The developers of caniuse-serde. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/caniuse-serde/master/COPYRIGHT.
//! # caniuse-serde
//!
//! A Rust library crate for working with the <https://caniuse.com> database of browser (agent) features and regional usage data.
//! Comes with a version if the database embedded, and can also be used with external copies (JSON files).
//!
//!
//! ## Getting Going
//!
//!
//! ### To get started
//!
//! ```
//! extern crate caniuse_serde;
//! use ::caniuse_serde::{EmbeddedCanIUseDatabase, AgentName, FeatureName};
//! ```
//!
//!
//! ### To look up an agent's details
//!
//! ```
//! let agent = AgentName::MozillaFirefox.agent(EmbeddedCanIUseDatabase).unwrap();
//! ```
//!
//!
//! ### To look up a feature's details
//!
//! ```
//! let feature = "transform3d".into().feature(EmbeddedCanIUseDatabase).unwrap();
//! ```
//!
//! ## Regional Usage
//!
//! * Use the constants in the `regional_usage` module to get regional, continental and world-wide usage data.
//! * To replicate the functionality of 'browserlist', use the `query()` method on RegionalUsage.
//! * Or read below for a more useful approach.
//! * Use the enum `RegionalUsages` with the method `regional_usage()` to obtain a reference to an embedded RegionalUsage database.
//!
//!
//! ## A strategy for using the caniuse database with [browserlist](https://github.com/ai/browserslist) like behaviour
//! The concept of version is differently understood by the browser vendors (eg IE vs Chrome, say), and so just saying 'last 2 versions' isn't particularly useful.
//! In practice, a combination of selection rules is needed to identify a set of browser and browser versions to support, using the data in the database. These selection rules are likely to be stable for months and years, but not in the long term.
//!
//! I've identified my own selection rules for a professional, international consultant's website written in English with translations to Spanish, French and Italian. I've added this as code to this crate to make sure that the API I've written around the caniuse.com database is actually usable.
//!
//!
//! ### To make use of my choices
//!
//! The quickest way is with either `sensible_choices()` or `sensible_choices_default()`:-
//!
//! ```
//! extern crate caniuse_serde;
//! use ::caniuse_serde::*;
//! use ::caniuse_serde::regional_usage::*;
//!
//! let (can_i_use, choices) = sensible_choices_default();
//!
//! let feature_name = FeatureName("css-focus-ring".to_owned());
//! let mut unique_prefixes = HashSet::new();
//! choices.support_for_a_feature(&can_i_use, &feature_name, |agent, version, support| {
//! if support.requires_prefix() {
//! unique_prefixes.insert(agent.prefix(version).clone());
//! }
//! });
//!
//! assert!(unique_prefixes.contains(&Prefix::moz));
//! assert_eq!(unique_prefixes.len(), 1);
//! ```
//!
//!
//! ### My selection rules
//! 1. Obsolete Browsers still in use
//! - We need to support the last version of these until its percentage usage falls below X%
//! - The percentage usage should be for a sub-set of the world (ie target audience continents or countries)
//! - These browsers are:-
//! - IE (at version 11)
//! - Blackberry Browser (at version 10)
//! - IE Mobile (MS has dropped Windows Phone)
//! 2. Browsers with major change of rendering engine
//! - This effectively makes the last version with the old rendering engine obsolete
//! - Rules as for Obsolete Browsers, but selection needs to be aware that there are 'later' versions
//! - These browsers are:-
//! - Android Browser (at 4.4.4)
//! - Opera with Presto
//! 3. Automatically Updated Browsers
//! - These browsers have short-lived, sub-yearly versions
//! - They are probably best discovered by matching for all released versions after a specific release date (eg 2 years ago)
//! - Using a percentage isn't wise as usage of each version will change rapidly (from near zero to a few percentage points, then to near zero again), and certainly likely to change more rapidly than static website rebuilds
//! - These browsers are:-
//! - Firefox
//! - Safari
//! - Microsoft Edge
//! - Chrome
//! - Opera with Webkit Rendering Engine
//! 4. Long-Term Releases of Automatically Updated Browsers
//! - These browsers have occasional long-term releases which are intended to be supported for a year or more
//! - Usage percentages for these may be very low globally, and they may be 9 or more release versions 'out-of-date', but they represent an important audience
//! - In practice the length of time each long term release is supported for changes with each release, even though vendors have 'long term release policies'
//! - This is because policies change in the long interval between long-term releases
//! - These browsers are problematic to identify as the caniuse.com database omits them
//! - Some long-term release versions differ slightly in supported features, particularly those of a more experimental nature, to their related short-term release cousins (even though they may share the same major version number)
//! - For Firefox, ESR releases are supposedly for one year (actually, 54 weeks, '9-cycles', with a 12-week ('2-cycle') overlap between releases (a cycle is a Firefox release cycle, typically 6 weeks), but, as always for these sorts of releases, the policy has changed several times.
//! - These browsers are:-
//! - Firefox
//! 5. Regionally significant, occasionally automatically updated browsers
//! - Support of these browsers is particularly important for the Indian and Asian markets
//! - Many cheaper smart phones come with them (I've used them, too)
//! - Vendors frequently don't upgrade old firmware installed versions and some older versions may persist and have higher usage for some time than newer ones
//! - All of them currently are just more dated versions of the Webkit rendering engine than Chrome
//! - These browsers are probably best supported with a 'above X% rule', where X is for any version
//! - These browsers are:-
//! - UC Browser
//! - Samsung Internet
//! - QQ Browser
//! - Baidu Browser
//! 6. Very different from mainstream and unsupportable
//! - Opera Mini is an excellent product, but unless one is explicitly targeting its users' demographic, it is not useful to support
//! - If one is targeting its users demographic, its lack of modern features (making it the lowest common denominator) means website development would not make use of caniuse.com data; it's too different.
extern crate chrono;
extern crate lazy_static;
extern crate maplit;
extern crate serde;
extern crate serde_derive;
extern crate serde_json;
extern crate url;
extern crate url_serde;
use *;
use Duration;
use *;
use de;
use Deserialize;
use DeserializeSeed;
use Deserializer;
use MapAccess;
use SeqAccess;
use Visitor;
use Bound;
use BTreeMap;
use HashMap;
use HashSet;
use Keys;
use Range;
use Ordering;
use Eq;
use Ord;
use PartialEq;
use PartialOrd;
use fmt;
use Display;
use Formatter;
use File;
use Hash;
use Hasher;
use Read;
use DoubleEndedIterator;
use ExactSizeIterator;
use Iterator;
use Add;
use AddAssign;
use Deref;
use Sub;
use SubAssign;
use Path;
use FromStr;
use Url;
/// Support for Agent regional, continental and world-wide usage by version.
/// Use the `RegionalUsages` enum preferably.
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;
include!;