Skip to main content

aptu_coder_core/
schema_helpers.rs

1// SPDX-FileCopyrightText: 2026 aptu-coder contributors
2// SPDX-License-Identifier: Apache-2.0
3#![cfg(feature = "schemars")]
4
5use schemars::Schema;
6use serde_json::json;
7
8/// Returns a plain integer schema without the non-standard "format": "uint"
9/// that schemars emits by default for usize/u32 fields.
10// SAFETY: json! macro always produces a Value::Object for object literals.
11#[allow(clippy::expect_used)]
12pub fn integer_schema(_gen: &mut schemars::SchemaGenerator) -> Schema {
13    let map = json!({
14        "type": "integer",
15        "minimum": 0
16    })
17    .as_object()
18    .expect("json! object literal is always a Value::Object")
19    .clone();
20    Schema::from(map)
21}
22
23/// Returns a nullable integer schema for Option<usize> / Option<u32> fields.
24// SAFETY: json! macro always produces a Value::Object for object literals.
25#[allow(clippy::expect_used)]
26pub fn option_integer_schema(_gen: &mut schemars::SchemaGenerator) -> Schema {
27    let map = json!({
28        "type": ["integer", "null"],
29        "minimum": 0
30    })
31    .as_object()
32    .expect("json! object literal is always a Value::Object")
33    .clone();
34    Schema::from(map)
35}
36
37/// Regex matching all supported source file extensions (case-insensitive).
38///
39/// Used as the `inputSchema` `pattern` constraint on `path` fields in
40/// `AnalyzeFileParams` and `AnalyzeModuleParams`. Covers every extension in
41/// `lang.rs` `EXTENSION_MAP`. Centralised here so adding a language requires
42/// one change, not two.
43pub const SUPPORTED_FILE_EXT_PATTERN: &str = r"(?i)\.(rs|py|go|ts|tsx|js|mjs|cjs|java|kt|kts|cs|cpp|cc|cxx|c|h|hpp|hxx|f|f77|f90|f95|f03|f08|for|ftn|html|htm|md|mdx|astro|css|yaml|yml|json|toml)$";
44
45/// Returns a string schema with a `pattern` constraint covering all supported
46/// source file extensions. Used as `schema_with` on `path` fields.
47// SAFETY: json! macro always produces a Value::Object for object literals.
48#[allow(clippy::expect_used)]
49pub fn supported_file_path_schema(_gen: &mut schemars::SchemaGenerator) -> Schema {
50    let map = serde_json::json!({
51        "type": "string",
52        "pattern": SUPPORTED_FILE_EXT_PATTERN
53    })
54    .as_object()
55    .expect("json! object literal is always a Value::Object")
56    .clone();
57    Schema::from(map)
58}
59
60/// Returns a nullable integer schema for `Option<usize>` `page_size` fields.
61/// Enforces minimum: 1 to prevent callers from sending `page_size=0`, which
62/// would cause `paginate_slice` to make no progress and loop on the same cursor.
63// SAFETY: json! macro always produces a Value::Object for object literals.
64#[allow(clippy::expect_used)]
65pub fn option_page_size_schema(_gen: &mut schemars::SchemaGenerator) -> Schema {
66    let map = json!({
67        "type": ["integer", "null"],
68        "minimum": 1
69    })
70    .as_object()
71    .expect("json! object literal is always a Value::Object")
72    .clone();
73    Schema::from(map)
74}