relay_ua/
lib.rs

1//! User agent parser with built-in rules.
2//!
3//! # Test Performance
4//!
5//! Adding user agent parsing to your module will incur a latency penalty on first use. Because of
6//! this, integration tests could fail. To fix this, you will need to add a timeout to your
7//! consumer.
8
9use once_cell::sync::Lazy;
10use uaparser::{Parser, UserAgentParser};
11
12#[doc(inline)]
13pub use uaparser::{Device, OS, UserAgent};
14
15/// The global [`UserAgentParser`] already configured with a user agent database.
16///
17/// For usage, see [`Parser`].
18static UA_PARSER: Lazy<UserAgentParser> = Lazy::new(|| {
19    let ua_regexes = include_bytes!("../uap-core/regexes.yaml");
20    UserAgentParser::builder()
21        .with_unicode_support(false)
22        .build_from_bytes(ua_regexes)
23        .expect("Could not create UserAgent. You are probably using a bad build of relay.")
24});
25
26/// Initializes the user agent parser.
27///
28/// This loads and compiles user agent patterns, which takes a few seconds to complete. The user
29/// agent parser initializes on-demand when using one of the parse methods. This function forces
30/// initialization at a convenient point without introducing unwanted delays.
31pub fn init_parser() {
32    Lazy::force(&UA_PARSER);
33}
34
35/// Returns the family and version of a user agent client.
36///
37/// Defaults to an empty user agent.
38pub fn parse_user_agent(user_agent: &str) -> UserAgent {
39    UA_PARSER.parse_user_agent(user_agent)
40}
41
42/// Returns the family, brand, and model of the device of the requesting client.
43///
44/// Defaults to an empty device.
45pub fn parse_device(user_agent: &str) -> Device {
46    UA_PARSER.parse_device(user_agent)
47}
48
49/// Returns the family and version of the operating system of the requesting client.
50///
51/// Defaults to an empty operating system.
52pub fn parse_os(user_agent: &str) -> OS {
53    UA_PARSER.parse_os(user_agent)
54}