caniuse_serde/
lib.rs

1// 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.
2// 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.
3
4
5//! # caniuse-serde
6//!
7//! A Rust library crate for working with the <https://caniuse.com> database of browser (agent) features and regional usage data.
8//! Comes with a version if the database embedded, and can also be used with external copies (JSON files).
9//!
10//!
11//! ## Getting Going
12//!
13//!
14//! ### To get started
15//!
16//! ```
17//! extern crate caniuse_serde;
18//! use ::caniuse_serde::{EmbeddedCanIUseDatabase, AgentName, FeatureName};
19//! ```
20//!
21//!
22//! ### To look up an agent's details
23//!
24//! ```
25//! let agent = AgentName::MozillaFirefox.agent(EmbeddedCanIUseDatabase).unwrap();
26//! ```
27//!
28//!
29//! ### To look up a feature's details
30//!
31//! ```
32//! let feature = "transform3d".into().feature(EmbeddedCanIUseDatabase).unwrap();
33//! ```
34//!
35//! ## Regional Usage
36//!
37//! * Use the constants in the `regional_usage` module to get regional, continental and world-wide usage data.
38//! * To replicate the functionality of 'browserlist', use the `query()` method on RegionalUsage.
39//! * Or read below for a more useful approach.
40//! * Use the enum `RegionalUsages` with the method `regional_usage()` to obtain a reference to an embedded RegionalUsage database.
41//!
42//!
43//! ## A strategy for using the caniuse database with [browserlist](https://github.com/ai/browserslist) like behaviour
44//! 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.
45//! 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.
46//!
47//! 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.
48//!
49//!
50//! ### To make use of my choices
51//!
52//! The quickest way is with either `sensible_choices()` or `sensible_choices_default()`:-
53//!
54//! ```
55//! extern crate caniuse_serde;
56//! use ::caniuse_serde::*;
57//! use ::caniuse_serde::regional_usage::*;
58//!
59//! let (can_i_use, choices) = sensible_choices_default();
60//!
61//! let feature_name = FeatureName("css-focus-ring".to_owned());
62//! let mut unique_prefixes = HashSet::new();
63//! choices.support_for_a_feature(&can_i_use, &feature_name, |agent, version, support| {
64//! 	if support.requires_prefix() {
65//! 		unique_prefixes.insert(agent.prefix(version).clone());
66//! 	}
67//! });
68//!
69//! assert!(unique_prefixes.contains(&Prefix::moz));
70//! assert_eq!(unique_prefixes.len(), 1);
71//! ```
72//!
73//!
74//! ### My selection rules
75//! 1. Obsolete Browsers still in use
76//! 	- We need to support the last version of these until its percentage usage falls below X%
77//! 	- The percentage usage should be for a sub-set of the world (ie target audience continents or countries)
78//! 	- These browsers are:-
79//!			- IE (at version 11)
80//! 		- Blackberry Browser (at version 10)
81//! 		- IE Mobile (MS has dropped Windows Phone)
82//! 2. Browsers with major change of rendering engine
83//! 	- This effectively makes the last version with the old rendering engine obsolete
84//! 	- Rules as for Obsolete Browsers, but selection needs to be aware that there are 'later' versions
85//! 	- These browsers are:-
86//!  		- Android Browser (at 4.4.4)
87//!			- Opera with Presto
88//! 3. Automatically Updated Browsers
89//! 	- These browsers have short-lived, sub-yearly versions
90//! 	- They are probably best discovered by matching for all released versions after a specific release date (eg 2 years ago)
91//! 	- 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
92//! 	- These browsers are:-
93//! 		- Firefox
94//! 		- Safari
95//! 		- Microsoft Edge
96//! 		- Chrome
97//! 		- Opera with Webkit Rendering Engine
98//! 4. Long-Term Releases of Automatically Updated Browsers
99//! 	- These browsers have occasional long-term releases which are intended to be supported for a year or more
100//! 	- 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
101//! 	- 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'
102//!		- This is because policies change in the long interval between long-term releases
103//! 	- These browsers are problematic to identify as the caniuse.com database omits them
104//! 	- 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)
105//!		- 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.
106//! 	- These browsers are:-
107//! 		- Firefox
108//! 5. Regionally significant, occasionally automatically updated browsers
109//! 	- Support of these browsers is particularly important for the Indian and Asian markets
110//! 	- Many cheaper smart phones come with them (I've used them, too)
111//! 	- 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
112//! 	- All of them currently are just more dated versions of the Webkit rendering engine than Chrome
113//! 	- These browsers are probably best supported with a 'above X% rule', where X is for any version
114//! 	- These browsers are:-
115//! 		- UC Browser
116//! 		- Samsung Internet
117//! 		- QQ Browser
118//! 		- Baidu Browser
119//! 6. Very different from mainstream and unsupportable
120//! 	- Opera Mini is an excellent product, but unless one is explicitly targeting its users' demographic, it is not useful to support
121//! 	- 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.
122
123
124#![allow(non_camel_case_types)]
125#![allow(non_snake_case)]
126#![allow(non_upper_case_globals)]
127#![deny(missing_copy_implementations)]
128#![deny(missing_debug_implementations)]
129#![deny(missing_docs)]
130#![deny(unstable_features)]
131#![deny(unused_extern_crates)]
132#![deny(unused_import_braces)]
133#![deny(unused_qualifications)]
134#![recursion_limit="1024"]
135
136
137extern crate chrono;
138#[macro_use] extern crate lazy_static;
139#[macro_use] extern crate maplit;
140extern crate serde;
141#[macro_use] extern crate serde_derive;
142extern crate serde_json;
143extern crate url;
144extern crate url_serde;
145
146
147use self::regional_usage::*;
148use ::chrono::Duration;
149use ::chrono::prelude::*;
150use ::serde::de;
151use ::serde::de::Deserialize;
152use ::serde::de::DeserializeSeed;
153use ::serde::de::Deserializer;
154use ::serde::de::MapAccess;
155use ::serde::de::SeqAccess;
156use ::serde::de::Visitor;
157use ::std::collections::Bound;
158use ::std::collections::BTreeMap;
159use ::std::collections::HashMap;
160use ::std::collections::HashSet;
161use ::std::collections::hash_map::Keys;
162use ::std::collections::btree_map::Range;
163use ::std::cmp::Ordering;
164use ::std::cmp::Eq;
165use ::std::cmp::Ord;
166use ::std::cmp::PartialEq;
167use ::std::cmp::PartialOrd;
168use ::std::fmt;
169use ::std::fmt::Display;
170use ::std::fmt::Formatter;
171use ::std::fs::File;
172use ::std::hash::Hash;
173use ::std::hash::Hasher;
174use ::std::io::Read;
175use ::std::iter::DoubleEndedIterator;
176use ::std::iter::ExactSizeIterator;
177use ::std::iter::Iterator;
178use ::std::ops::Add;
179use ::std::ops::AddAssign;
180use ::std::ops::Deref;
181use ::std::ops::Sub;
182use ::std::ops::SubAssign;
183use ::std::path::Path;
184use ::std::str::FromStr;
185use ::url::Url;
186
187
188#[cfg(test)] mod systemTests;
189
190/// Support for Agent regional, continental and world-wide usage by version.
191/// Use the `RegionalUsages` enum preferably.
192pub mod regional_usage;
193
194
195
196include!("Agent.rs");
197include!("AgentDetail.rs");
198include!("AgentName.rs");
199include!("AgentNameIterator.rs");
200include!("AgentNameAndVersionSet.rs");
201include!("AgentType.rs");
202include!("Bug.rs");
203include!("CanIUse.rs");
204include!("Category.rs");
205include!("Feature.rs");
206include!("FeatureDetail.rs");
207include!("FeatureName.rs");
208include!("FeatureNameIterator.rs");
209include!("Link.rs");
210include!("ParentCategory.rs");
211include!("ParentCategoryIterator.rs");
212include!("Prefix.rs");
213include!("PrefixVisitor.rs");
214include!("sensible_choices.rs");
215include!("sensible_choices_default.rs");
216include!("Status.rs");
217include!("StatusIterator.rs");
218include!("Support.rs");
219include!("SupportDetail.rs");
220include!("SupportRangeIterator.rs");
221include!("SupportMaturity.rs");
222include!("UsagePercentage.rs");
223include!("Version.rs");
224include!("VersionDetail.rs");
225include!("VersionPart.rs");