use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use mant_ir::{ResolvedContent, TldrDocument};
use crate::{
DocumentAddress, DocumentResponse, NodeSelector, OutlineDetail, SearchCase, SearchScope,
SearchSyntax, default_search_limit,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub enum QuerySchema {
#[serde(rename = "mant.query/v7")]
V7,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub enum RequestSchema {
#[serde(rename = "mant.request/v7")]
V7,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(
tag = "kind",
rename_all = "kebab-case",
rename_all_fields = "camelCase",
deny_unknown_fields
)]
pub enum QueryInput {
Document {
selector: String,
#[serde(skip_serializing_if = "Option::is_none")]
source: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
manual_section: Option<String>,
},
File {
path: String,
format: InputFormat,
},
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "kebab-case")]
pub enum InputFormat {
#[default]
Auto,
Markdown,
Roff,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(
tag = "kind",
rename_all = "kebab-case",
rename_all_fields = "camelCase",
deny_unknown_fields
)]
pub enum QueryView {
Full {},
Outline {
detail: OutlineDetail,
},
Excerpt {
#[schemars(length(min = 1))]
selectors: Vec<NodeSelector>,
},
Explain {
#[schemars(length(min = 1))]
entry: String,
},
Search {
#[schemars(length(min = 1, max = 4096))]
pattern: String,
#[serde(default)]
syntax: SearchSyntax,
#[serde(default)]
case: SearchCase,
#[serde(default)]
scope: SearchScope,
#[serde(default)]
word: bool,
#[serde(default)]
#[schemars(range(max = 100))]
context_lines: u16,
#[serde(default = "default_search_limit")]
#[schemars(range(min = 1, max = 10000))]
limit: u32,
#[serde(default)]
offset: u32,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
#[schemars(extend("$id" = "urn:mant:request:v7"))]
pub struct QueryRequest {
pub schema: RequestSchema,
pub input: QueryInput,
pub view: QueryView,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(extend("$id" = "urn:mant:query:v7"))]
pub struct QueryBundle {
pub schema: QuerySchema,
pub label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub address: Option<DocumentAddress>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document: Option<DocumentResponse>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tldr: Option<TldrDocument>,
}
impl From<&ResolvedContent> for QueryBundle {
fn from(content: &ResolvedContent) -> Self {
Self {
schema: QuerySchema::V7,
label: content.label.clone(),
address: content.address.clone(),
document: content.document.as_ref().map(Into::into),
tldr: content.tldr.clone(),
}
}
}
impl From<QueryBundle> for ResolvedContent {
fn from(bundle: QueryBundle) -> Self {
Self {
label: bundle.label,
address: bundle.address,
document: bundle.document.map(Into::into),
tldr: bundle.tldr,
}
}
}