drizzle_postgres/expr/regex.rs
1//! `PostgreSQL` regular expression operators.
2//!
3//! Provides type-safe access to `PostgreSQL` regex operators:
4//! - `~` (matches regex, case-sensitive)
5//! - `~*` (matches regex, case-insensitive)
6//! - `!~` (does not match regex, case-sensitive)
7//! - `!~*` (does not match regex, case-insensitive)
8
9use crate::values::PostgresValue;
10use drizzle_core::expr::{Expr, NonNull, SQLExpr, Scalar};
11use drizzle_core::sql::{SQL, SQLChunk};
12use drizzle_types::postgres::types::Boolean;
13
14/// `PostgreSQL` `~` operator - case-sensitive regex match.
15///
16/// # Example
17///
18/// ```
19/// # use drizzle_postgres::expr::regex_match;
20/// # use drizzle_core::{SQL, ToSQL};
21/// # use drizzle_postgres::values::PostgresValue;
22/// let name = SQL::<PostgresValue>::raw("name");
23/// let cond = regex_match(name, "^[A-Z]");
24/// assert!(cond.to_sql().sql().contains("~"));
25/// ```
26pub fn regex_match<'a, E>(
27 expr: E,
28 pattern: &'a str,
29) -> SQLExpr<'a, PostgresValue<'a>, Boolean, NonNull, Scalar>
30where
31 E: Expr<'a, PostgresValue<'a>>,
32{
33 SQLExpr::new(
34 expr.to_sql()
35 .push(SQLChunk::Raw("~".into()))
36 .append(SQL::param(PostgresValue::Text(pattern.into()))),
37 )
38}
39
40/// `PostgreSQL` `~*` operator - case-insensitive regex match.
41///
42/// # Example
43///
44/// ```
45/// # use drizzle_postgres::expr::regex_match_ci;
46/// # use drizzle_core::{SQL, ToSQL};
47/// # use drizzle_postgres::values::PostgresValue;
48/// let name = SQL::<PostgresValue>::raw("name");
49/// let cond = regex_match_ci(name, "^john");
50/// assert!(cond.to_sql().sql().contains("~*"));
51/// ```
52pub fn regex_match_ci<'a, E>(
53 expr: E,
54 pattern: &'a str,
55) -> SQLExpr<'a, PostgresValue<'a>, Boolean, NonNull, Scalar>
56where
57 E: Expr<'a, PostgresValue<'a>>,
58{
59 SQLExpr::new(
60 expr.to_sql()
61 .push(SQLChunk::Raw("~*".into()))
62 .append(SQL::param(PostgresValue::Text(pattern.into()))),
63 )
64}
65
66/// `PostgreSQL` `!~` operator - case-sensitive regex non-match.
67///
68/// # Example
69///
70/// ```
71/// # use drizzle_postgres::expr::regex_not_match;
72/// # use drizzle_core::{SQL, ToSQL};
73/// # use drizzle_postgres::values::PostgresValue;
74/// let name = SQL::<PostgresValue>::raw("name");
75/// let cond = regex_not_match(name, "^[0-9]");
76/// assert!(cond.to_sql().sql().contains("!~"));
77/// ```
78pub fn regex_not_match<'a, E>(
79 expr: E,
80 pattern: &'a str,
81) -> SQLExpr<'a, PostgresValue<'a>, Boolean, NonNull, Scalar>
82where
83 E: Expr<'a, PostgresValue<'a>>,
84{
85 SQLExpr::new(
86 expr.to_sql()
87 .push(SQLChunk::Raw("!~".into()))
88 .append(SQL::param(PostgresValue::Text(pattern.into()))),
89 )
90}
91
92/// `PostgreSQL` `!~*` operator - case-insensitive regex non-match.
93///
94/// # Example
95///
96/// ```
97/// # use drizzle_postgres::expr::regex_not_match_ci;
98/// # use drizzle_core::{SQL, ToSQL};
99/// # use drizzle_postgres::values::PostgresValue;
100/// let name = SQL::<PostgresValue>::raw("name");
101/// let cond = regex_not_match_ci(name, "^admin");
102/// assert!(cond.to_sql().sql().contains("!~*"));
103/// ```
104pub fn regex_not_match_ci<'a, E>(
105 expr: E,
106 pattern: &'a str,
107) -> SQLExpr<'a, PostgresValue<'a>, Boolean, NonNull, Scalar>
108where
109 E: Expr<'a, PostgresValue<'a>>,
110{
111 SQLExpr::new(
112 expr.to_sql()
113 .push(SQLChunk::Raw("!~*".into()))
114 .append(SQL::param(PostgresValue::Text(pattern.into()))),
115 )
116}
117
118/// Extension trait providing method-based regex operators for `PostgreSQL` expressions.
119pub trait RegexExprExt<'a>: Expr<'a, PostgresValue<'a>> + Sized {
120 /// Case-sensitive regex match (`~` operator).
121 fn regex_match(
122 self,
123 pattern: &'a str,
124 ) -> SQLExpr<'a, PostgresValue<'a>, Boolean, NonNull, Scalar> {
125 regex_match(self, pattern)
126 }
127
128 /// Case-insensitive regex match (`~*` operator).
129 fn regex_match_ci(
130 self,
131 pattern: &'a str,
132 ) -> SQLExpr<'a, PostgresValue<'a>, Boolean, NonNull, Scalar> {
133 regex_match_ci(self, pattern)
134 }
135
136 /// Case-sensitive regex non-match (`!~` operator).
137 fn regex_not_match(
138 self,
139 pattern: &'a str,
140 ) -> SQLExpr<'a, PostgresValue<'a>, Boolean, NonNull, Scalar> {
141 regex_not_match(self, pattern)
142 }
143
144 /// Case-insensitive regex non-match (`!~*` operator).
145 fn regex_not_match_ci(
146 self,
147 pattern: &'a str,
148 ) -> SQLExpr<'a, PostgresValue<'a>, Boolean, NonNull, Scalar> {
149 regex_not_match_ci(self, pattern)
150 }
151}
152
153/// Blanket implementation for all `PostgreSQL` `Expr` types.
154impl<'a, E: Expr<'a, PostgresValue<'a>>> RegexExprExt<'a> for E {}