haematite-cli 0.21.8

The haematite command: serve a store, its door and Studio, answer MCP, query with jq, and host the store's assistant seat
Documentation
//! Language answers depend only on the request text and the word table.

use serde::{Deserialize, Serialize};
use serde_json::{Value, json};

use super::{parser, words as vocabulary};
use crate::serve::storage::Failure;

#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CheckRequest {
    pub query: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct WordsRequest {}

#[must_use]
pub fn check(request: &CheckRequest) -> Value {
    let mut stages = Vec::new();
    let parsed = parser::pipeline_with(&request.query, |word, span| {
        stages.push(json!({"word": word, "span": {"start": span.start, "end": span.end}}));
    });
    let refusal = parsed.err().map(|refused| {
        let span = refused.span();
        json!({
            "code": refused.code(),
            "message": refused.to_string(),
            "span": {"start": span.start, "end": span.end}
        })
    });
    json!({"stages": stages, "refusal": refusal})
}

/// Serialize the served query word table.
///
/// # Errors
/// Returns `storage_unavailable` if serializing the word table fails.
pub fn words(request: &WordsRequest) -> Result<Value, Failure> {
    let WordsRequest {} = request;
    serde_json::to_value(vocabulary::WORDS).map_err(Failure::storage)
}