Skip to main content

chain_builder/
like.rs

1//! `LIKE`-pattern escaping helper.
2
3/// Escape `\`, `%`, and `_` so user input matches **literally** inside a
4/// `LIKE`/`ILIKE` pattern. The caller still wraps the result in `%…%` /
5/// `…%` as needed — and the result stays a **bind value** (pass it through
6/// `where_like`/a placeholder as usual; never splice it into the SQL text).
7///
8/// Backslash is escaped first (order matters), then `%` and `_`:
9///
10/// ```
11/// use chain_builder::escape_like;
12/// assert_eq!(escape_like("100%_a\\b"), "100\\%\\_a\\\\b");
13/// assert_eq!(format!("%{}%", escape_like("50%")), "%50\\%%");
14/// ```
15///
16/// # Portability caveat
17///
18/// What `\` means inside a `LIKE` pattern is dialect-defined: Postgres and
19/// MySQL treat backslash as the default escape character, but **SQLite has
20/// no default escape character at all**. For fully portable literal
21/// matching, pair the escaped pattern with an explicit `ESCAPE '\'` clause
22/// via `where_raw` (on MySQL write the literal as `ESCAPE '\\'`). See the
23/// search-pattern chapter of the book for the full recipe.
24///
25/// Covers the metacharacters of the supported dialects (Postgres, MySQL,
26/// SQLite). `[` — a `LIKE` metacharacter on SQL Server only — is **not**
27/// escaped.
28pub fn escape_like(input: &str) -> String {
29    input
30        .replace('\\', "\\\\")
31        .replace('%', "\\%")
32        .replace('_', "\\_")
33}