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 std::sync::LazyLock;
10
11use uaparser::{Parser, UserAgentParser};
12
13#[doc(inline)]
14pub use uaparser::{Device, OS, UserAgent};
15
16/// The global [`UserAgentParser`] already configured with a user agent database.
17///
18/// For usage, see [`Parser`].
19static UA_PARSER: LazyLock<UserAgentParser> = LazyLock::new(|| {
20    let ua_regexes = include_bytes!("../uap-core/regexes.yaml");
21    UserAgentParser::builder()
22        .with_unicode_support(false)
23        .build_from_bytes(ua_regexes)
24        .expect("Could not create UserAgent. You are probably using a bad build of relay.")
25});
26
27/// Initializes the user agent parser.
28///
29/// This loads and compiles user agent patterns, which takes a few seconds to complete. The user
30/// agent parser initializes on-demand when using one of the parse methods. This function forces
31/// initialization at a convenient point without introducing unwanted delays.
32pub fn init_parser() {
33    LazyLock::force(&UA_PARSER);
34}
35
36/// Returns the family and version of a user agent client.
37///
38/// Defaults to an empty user agent.
39pub fn parse_user_agent(user_agent: &str) -> UserAgent<'_> {
40    UA_PARSER.parse_user_agent(user_agent)
41}
42
43/// Returns the family, brand, and model of the device of the requesting client.
44///
45/// Defaults to an empty device.
46pub fn parse_device(user_agent: &str) -> Device<'_> {
47    UA_PARSER.parse_device(user_agent)
48}
49
50/// Returns the family and version of the operating system of the requesting client.
51///
52/// Defaults to an empty operating system.
53pub fn parse_os(user_agent: &str) -> OS<'_> {
54    UA_PARSER.parse_os(user_agent)
55}