crtx-reflect 0.1.1

Reflection orchestration, prompts, candidate parsing, and schema validation.
Documentation
//! Parsers for reflection JSON contracts.

use schemars::schema_for;

use crate::error::ReflectError;
use crate::schema::{PrincipleCandidateBatch, SessionReflection};

/// Parse and validate a `SessionReflection` JSON object.
///
/// Failures preserve the original input for quarantine. This function performs
/// syntax validation, serde/schema shape validation, and local invariant checks
/// such as confidence ranges and candidate index bounds.
pub fn parse_reflection(input: &str) -> Result<SessionReflection, ReflectError> {
    let value = parse_value(input)?;
    let reflection: SessionReflection =
        serde_json::from_value(value).map_err(|source| ReflectError::InvalidSchema {
            raw: input.to_string(),
            message: source.to_string(),
        })?;
    reflection
        .validate()
        .map_err(|message| ReflectError::InvalidSchema {
            raw: input.to_string(),
            message,
        })?;
    Ok(reflection)
}

/// Parse and validate a `PrincipleCandidate` batch JSON object.
pub fn parse_principle_candidates(input: &str) -> Result<PrincipleCandidateBatch, ReflectError> {
    let value = parse_value(input)?;
    let batch: PrincipleCandidateBatch =
        serde_json::from_value(value).map_err(|source| ReflectError::InvalidSchema {
            raw: input.to_string(),
            message: source.to_string(),
        })?;
    batch
        .validate()
        .map_err(|message| ReflectError::InvalidSchema {
            raw: input.to_string(),
            message,
        })?;
    Ok(batch)
}

/// Export the `SessionReflection` JSON Schema as a JSON value.
#[must_use]
pub fn session_reflection_json_schema() -> serde_json::Value {
    serde_json::to_value(schema_for!(SessionReflection)).expect("schema is serializable")
}

/// Export the `PrincipleCandidateBatch` JSON Schema as a JSON value.
#[must_use]
pub fn principle_candidate_batch_json_schema() -> serde_json::Value {
    serde_json::to_value(schema_for!(PrincipleCandidateBatch)).expect("schema is serializable")
}

fn parse_value(input: &str) -> Result<serde_json::Value, ReflectError> {
    serde_json::from_str(input).map_err(|source| ReflectError::InvalidJson {
        raw: input.to_string(),
        message: source.to_string(),
    })
}