# mimic-rs
High-performance User-Agent to Sec-CH-UA Client Hints converter for Rust.
[](https://crates.io/crates/mimic-rs)
[](https://docs.rs/mimic-rs)
[](https://opensource.org/licenses/MIT)
## Overview
`mimic-rs` parses User-Agent strings from Chromium-based browsers and generates the corresponding `Sec-CH-UA` (Client Hints) headers. This is useful for:
- HTTP clients that need to send proper Client Hints headers
- Browser fingerprinting research
- Web scraping with accurate browser emulation
- Testing servers that rely on Client Hints
## Features
- Zero-copy parsing where possible
- Support for Chrome, Edge, Brave, Opera, Vivaldi, Samsung Internet, Yandex, and generic Chromium
- Accurate greased brand generation matching Chromium's algorithm
- Platform detection (Windows, macOS, Linux, Android, Chrome OS)
- Mobile browser detection
- Optional `serde` support for serialization
- No unsafe code
## Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
mimic-rs = "0.1"
```
With serde support:
```toml
[dependencies]
mimic-rs = { version = "0.1", features = ["serde"] }
```
## Usage
### Basic Usage
```rust
use mimic_rs::ClientHints;
fn main() {
let user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 \
(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
let hints = ClientHints::from_ua(user_agent).unwrap();
println!("sec-ch-ua: {}", hints.sec_ch_ua());
println!("sec-ch-ua-mobile: {}", hints.sec_ch_ua_mobile());
println!("sec-ch-ua-platform: {}", hints.sec_ch_ua_platform());
}
```
Output:
```
sec-ch-ua: "Not A(Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
```
### Manual Construction
```rust
use mimic_rs::{ClientHints, Brand, Platform};
let hints = ClientHints::new(
Brand::Chrome,
120,
"120.0.6099.129",
Platform::Windows,
false,
);
println!("sec-ch-ua: {}", hints.sec_ch_ua());
println!("sec-ch-ua-full-version-list: {}", hints.sec_ch_ua_full_version_list());
```
### Getting All Headers at Once
```rust
use mimic_rs::ClientHints;
let ua = "Mozilla/5.0 (Linux; Android 13) Chrome/120.0.0.0 Mobile Safari/537.36";
let hints = ClientHints::from_ua(ua).unwrap();
let (sec_ch_ua, sec_ch_ua_mobile, sec_ch_ua_platform) = hints.all_headers();
```
### Supported Browsers
| Chrome | `Chrome/` | `Google Chrome` |
| Edge | `Edg/`, `EdgA/`, `EdgiOS/` | `Microsoft Edge` |
| Brave | `Brave` | `Brave` |
| Opera | `OPR/`, `Opera/` | `Opera` |
| Vivaldi | `Vivaldi/` | `Vivaldi` |
| Samsung Internet | `SamsungBrowser/` | `Samsung Internet` |
| Yandex | `YaBrowser/`, `Yandex/` | `Yandex Browser` |
| Chromium | `Chromium/` | `Chromium` |
### Supported Platforms
- Windows
- macOS
- Linux
- Android
- Chrome OS
## API Reference
### `ClientHints`
Main struct containing parsed browser information.
#### Methods
- `from_ua(user_agent: &str) -> Result<ClientHints, ParseError>` - Parse a User-Agent string
- `new(brand, major_version, full_version, platform, is_mobile)` - Create manually
- `brand() -> Brand` - Get the detected browser brand
- `major_version() -> u32` - Get the major version number
- `full_version() -> &str` - Get the full version string
- `platform() -> Platform` - Get the detected platform
- `is_mobile() -> bool` - Check if mobile browser
- `sec_ch_ua() -> String` - Generate `sec-ch-ua` header value
- `sec_ch_ua_full_version_list() -> String` - Generate `sec-ch-ua-full-version-list` header
- `sec_ch_ua_mobile() -> &'static str` - Generate `sec-ch-ua-mobile` header (`?0` or `?1`)
- `sec_ch_ua_platform() -> String` - Generate `sec-ch-ua-platform` header
- `all_headers() -> (String, &'static str, String)` - Get all three main headers
### `Brand`
Enum representing browser brands:
- `Chrome`, `Edge`, `Brave`, `Opera`, `Vivaldi`, `Samsung`, `Yandex`, `Chromium`
### `Platform`
Enum representing operating systems:
- `Windows`, `MacOS`, `Linux`, `Android`, `ChromeOS`, `Unknown`
### `ParseError`
Error types:
- `EmptyUserAgent` - Empty input string
- `NotChromiumBased` - Not a Chromium browser
- `InvalidVersion` - Could not parse version
- `ChromeTokenNotFound` - No Chrome/Chromium token found
## Performance
The library is optimized for speed:
- No regex dependencies
- Minimal allocations
- Preallocated string buffers
- `#[inline]` on hot paths
Run benchmarks:
```bash
cargo bench
```
## How Greased Brands Work
Chromium browsers include a "greased" fake brand in the `sec-ch-ua` header to prevent servers from relying on specific patterns. The greased brand changes based on the major version:
- Characters cycle through: ` `, `(`, `:`, `-`, `.`
- Versions cycle through: `8`, `99`, `24`
- Order of brands is permuted based on version
This library accurately replicates Chromium's greasing algorithm.
## License
MIT License - see [LICENSE](LICENSE) for details.
## Acknowledgments
Inspired by [mimic](https://github.com/saucesteals/mimic) (Go).