sqlxo 0.9.1

sqlxo: small SQL query builder + derives for filterable ORM-ish patterns
Documentation
use serde::{
	Deserialize,
	Serialize,
};
use sqlxo_traits::{
	WebLeaf,
	WebQueryModel,
	WebSortField,
};
use utoipa::{
	IntoParams,
	ToSchema,
};

mod builder;
mod page;
pub use page::{
	WebPage,
	WebPagination,
};
pub use sqlxo_traits::WebQueryError;

#[derive(
	Clone, Serialize, Deserialize, ToSchema, Debug, Default, IntoParams,
)]
#[serde(bound(deserialize = "Q: WebLeaf + Deserialize<'de>, S: \
                             WebSortField + Deserialize<'de>"))]
#[serde(deny_unknown_fields)]
#[into_params(parameter_in = Query)]
pub struct GenericWebFilter<Q, S>
where
	Q: WebLeaf + Serialize,
	S: WebSortField + Serialize,
{
	#[schema(no_recursion, nullable)]
	pub filter:    Option<GenericWebExpression<Q>>,
	#[schema(no_recursion, nullable)]
	pub sort:      Option<Vec<GenericWebSort<S>>>,
	#[schema(no_recursion, nullable)]
	pub search:    Option<String>,
	/// Zero-based page index.
	#[schema(nullable)]
	#[param(rename = "pageNo", example = 0)]
	#[serde(
		default,
		rename = "pageNo",
		deserialize_with = "crate::web::page::opt_non_negative_i64"
	)]
	pub page_no:   Option<i64>,
	/// Maximum number of elements to return.
	#[schema(nullable)]
	#[param(rename = "pageSize", example = 10)]
	#[serde(
		default,
		rename = "pageSize",
		deserialize_with = "crate::web::page::opt_positive_i64"
	)]
	pub page_size: Option<i64>,
}

#[derive(Clone, Serialize, Deserialize, ToSchema, Debug, IntoParams)]
#[serde(bound(deserialize = "Q: WebLeaf + Deserialize<'de>"))]
#[serde(deny_unknown_fields)]
#[into_params(parameter_in = Query)]
pub struct GenericWebMutationFilter<Q>
where
	Q: WebLeaf + Serialize,
{
	#[schema(no_recursion, nullable)]
	pub filter: Option<GenericWebExpression<Q>>,
}

#[derive(Clone, Serialize, Deserialize, ToSchema, Debug)]
#[serde(bound(deserialize = "Q: WebLeaf + Deserialize<'de>"))]
#[serde(untagged)]
pub enum GenericWebExpression<Q>
where
	Q: WebLeaf + Serialize,
{
	#[schema(no_recursion)]
	And {
		and: Vec<GenericWebExpression<Q>>,
	},
	#[schema(no_recursion)]
	Or {
		or: Vec<GenericWebExpression<Q>>,
	},
	Leaf(Q),
}

#[derive(Clone, Serialize, Deserialize, ToSchema, Debug)]
#[serde(bound(deserialize = "S: WebSortField + Deserialize<'de>"))]
#[serde(transparent)]
pub struct GenericWebSort<S>(pub S)
where
	S: WebSortField + Serialize;

pub type WebExpression<T> = GenericWebExpression<<T as WebQueryModel>::Leaf>;
pub type WebSort<T> = GenericWebSort<<T as WebQueryModel>::SortField>;
pub type WebReadFilter<T> = GenericWebFilter<
	<T as WebQueryModel>::Leaf,
	<T as WebQueryModel>::SortField,
>;
pub type WebFilter<T> = WebReadFilter<T>;
pub type WebUpdateFilter<T> =
	GenericWebMutationFilter<<T as WebQueryModel>::Leaf>;
pub type WebDeleteFilter<T> =
	GenericWebMutationFilter<<T as WebQueryModel>::Leaf>;