sift_query_sqlx/web/
mod.rs1use sift_query_core::{ParamError, QueryLimits, RawParams};
8
9use crate::PgSearchError;
10
11mod search;
12pub use search::{SearchParamConfig, SearchParams};
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct QueryParams(pub RawParams);
16
17impl QueryParams {
18 pub fn parse(query: Option<&str>) -> Result<Self, ParamError> {
19 RawParams::parse(query.unwrap_or_default()).map(Self)
20 }
21
22 pub fn parse_with_limits(
23 query: Option<&str>,
24 limits: &QueryLimits,
25 ) -> Result<Self, ParamError> {
26 RawParams::parse_with_limits(query.unwrap_or_default(), limits).map(Self)
27 }
28
29 #[must_use]
30 pub fn raw(&self) -> &RawParams {
31 &self.0
32 }
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub struct WebError(pub PublicError);
39
40impl std::fmt::Display for WebError {
41 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 formatter.write_str(self.0.code)
43 }
44}
45impl std::error::Error for WebError {}
46impl From<PgSearchError> for WebError {
47 fn from(error: PgSearchError) -> Self {
48 Self(public_error(&error))
49 }
50}
51impl From<ParamError> for WebError {
52 fn from(error: ParamError) -> Self {
53 if error == ParamError::QueryTooLong {
54 return search::error(413, "query_too_long");
55 }
56 Self(PublicError {
57 status: 400,
58 code: "invalid_query",
59 })
60 }
61}
62impl PublicError {
63 #[must_use]
64 pub fn body(self) -> String {
65 format!("{{\"error\":{{\"code\":\"{}\"}}}}", self.code)
66 }
67}
68
69#[cfg(feature = "actix-web")]
70mod actix;
71#[cfg(feature = "axum")]
72mod axum;
73#[cfg(feature = "poem")]
74mod poem;
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
77pub struct PublicError {
78 pub status: u16,
79 pub code: &'static str,
80}
81
82#[must_use]
83pub fn public_error(error: &PgSearchError) -> PublicError {
84 match error {
85 PgSearchError::Param(ParamError::QueryTooLong)
86 | PgSearchError::Plan(sift_query_core::PlanError::Param(ParamError::QueryTooLong)) => {
87 WebError::from(ParamError::QueryTooLong).0
88 }
89 PgSearchError::Param(_) | PgSearchError::Plan(sift_query_core::PlanError::Param(_)) => {
90 PublicError {
91 status: 400,
92 code: "invalid_query",
93 }
94 }
95 PgSearchError::Timeout(_)
96 | PgSearchError::Extension(crate::ExtensionError::LabelTimeout) => PublicError {
97 status: 504,
98 code: "query_timeout",
99 },
100 PgSearchError::ScanLimitExceeded { .. } => PublicError {
101 status: 413,
102 code: "scan_limit_exceeded",
103 },
104 _ => PublicError {
105 status: 500,
106 code: "query_failed",
107 },
108 }
109}