use schemars::JsonSchema;
#[derive(JsonSchema)]
#[schemars(rename_all = "snake_case")]
pub enum FilterLogic {
And,
Or,
}
#[derive(JsonSchema)]
#[schemars(rename_all = "snake_case")]
pub enum FilterOperator {
Eq,
Ne,
Gt,
Gte,
Lt,
Lte,
In,
NotIn,
Contains,
StartsWith,
EndsWith,
Like,
#[schemars(rename = "ilike")]
ILike,
Between,
IsNull,
IsNotNull,
Regex,
Empty,
NotEmpty,
Exists,
}
#[derive(JsonSchema)]
#[schemars(rename_all = "snake_case")]
pub enum SearchFieldMode {
Prefix,
Contains,
Exact,
}
#[derive(JsonSchema)]
#[schemars(rename_all = "snake_case")]
pub enum FuzzyMode {
Exact,
Fuzzy,
TokenSort,
}
#[derive(JsonSchema)]
#[schemars(rename_all = "snake_case")]
pub enum SortDirection {
Asc,
Desc,
}
#[derive(JsonSchema)]
#[schemars(rename_all = "snake_case")]
pub enum NullsPosition {
First,
Last,
}
#[derive(JsonSchema)]
pub struct FilterSpec {
pub field: String,
pub operator: FilterOperator,
pub value: serde_json::Value,
pub logic: Option<FilterLogic>,
}
#[derive(JsonSchema)]
#[schemars(untagged)]
pub enum FilterNode {
Spec(FilterSpec),
Group(FilterGroup),
}
#[derive(JsonSchema)]
pub struct FilterGroup {
pub logic: FilterLogic,
pub conditions: Vec<FilterNode>,
}
#[derive(JsonSchema)]
pub struct SortSpec {
pub field: String,
pub direction: Option<SortDirection>,
pub nulls: Option<NullsPosition>,
}
#[derive(JsonSchema)]
pub struct SearchSpec {
pub query: String,
pub fields: Vec<String>,
pub mode: Option<SearchFieldMode>,
pub fuzzy: Option<FuzzyMode>,
pub threshold: Option<i64>,
pub min_length: Option<i64>,
pub max_results: Option<i64>,
pub weights: Option<std::collections::BTreeMap<String, f64>>,
}
#[derive(JsonSchema)]
pub struct OffsetParams {
pub page: i64,
pub limit: i64,
}
#[derive(JsonSchema)]
pub struct CursorParams {
pub limit: i64,
pub after: Option<String>,
pub before: Option<String>,
}
#[derive(JsonSchema)]
pub struct OffsetPageMeta {
pub total: i64,
pub page: i64,
pub pages: i64,
pub limit: i64,
pub has_next: bool,
pub has_previous: bool,
}
#[derive(JsonSchema)]
pub struct CursorPageMeta {
pub limit: i64,
pub has_next: bool,
pub has_previous: bool,
pub next_cursor: Option<String>,
pub previous_cursor: Option<String>,
}
#[cfg(test)]
mod export {
use super::{
CursorPageMeta, CursorParams, FilterGroup, FilterSpec, OffsetPageMeta, OffsetParams,
SearchSpec, SortSpec,
};
use schemars::SchemaGenerator;
#[test]
fn export_schema() {
let mut generator = SchemaGenerator::default();
generator.subschema_for::<FilterSpec>();
generator.subschema_for::<FilterGroup>();
generator.subschema_for::<SortSpec>();
generator.subschema_for::<SearchSpec>();
generator.subschema_for::<OffsetParams>();
generator.subschema_for::<CursorParams>();
generator.subschema_for::<OffsetPageMeta>();
generator.subschema_for::<CursorPageMeta>();
let doc = serde_json::json!({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "paginate",
"$defs": generator.take_definitions(true),
});
let json = serde_json::to_string_pretty(&doc).expect("schema serializes");
let dir = concat!(env!("CARGO_MANIFEST_DIR"), "/../../schemas");
std::fs::create_dir_all(dir).expect("create schemas dir");
std::fs::write(format!("{dir}/paginate.schema.json"), json + "\n").expect("write schema");
}
}