Skip to main content

asimov_patterns/programs/
compiler.rs

1// This is free and unencumbered software released into the public domain.
2
3//! Natural-language query compilation: the compiler marker trait and arguments.
4
5use crate::Execute;
6use alloc::{string::String, vec::Vec};
7use bon::Builder;
8
9/// A prompt compiler that translates natural-language text into one SPARQL query.
10///
11/// The query is intended for an [`Adapter`](crate::Adapter); compiling it does
12/// not execute it. The program documents its assumptions about the target
13/// dataset, vocabulary, and adapter capabilities. Syntactic validity alone does
14/// not guarantee that a query captures the author's intent.
15///
16/// # Command-line contract
17///
18/// `PROGRAM [OPTIONS] [INPUT-FILE]`
19///
20/// The natural-language input file defaults to `-` (stdin). On success, stdout
21/// contains a syntactically valid SPARQL query as UTF-8, without Markdown fences
22/// or explanatory prose outside the query. The query must produce a graph or
23/// use a form for which the intended adapter's profile defines an RDF mapping.
24/// There are no standard pattern-specific options or output-file operand.
25///
26/// `T` is the implementation's query representation. See [`crate::programs`]
27/// for links to concrete execution behavior and the [compiler specification][spec].
28///
29/// [spec]: https://asimov-specs.github.io/program-patterns/#compiler
30pub trait Compiler<T>: Execute<T> {}
31
32/// Additional arguments and an optional input file for a [`Compiler`].
33///
34/// `Default` creates an empty argument list, selecting the program's stdin-input
35/// form. The pattern defines no standard model or format options. Any such
36/// options supplied through [`other`](Self::other) are extensions requiring
37/// support from the selected program; this type does not validate that support.
38///
39/// # Examples
40///
41/// Select a named input file as one literal argument, retaining stdout output:
42///
43/// ```
44/// use asimov_patterns::CompilerOptions;
45///
46/// let options = CompilerOptions::builder()
47///     .other("--")
48///     .other("request with spaces.txt")
49///     .build();
50/// ```
51#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Builder)]
52#[builder(derive(Debug), on(String, into))]
53pub struct CompilerOptions {
54    /// Literal command-line arguments, including an optional input-file operand.
55    ///
56    /// The process wrapper forwards these in order and generates no other
57    /// arguments. Put extension options before the input file. Each string is
58    /// one argument, without shell expansion; see [`crate::programs`]. With a
59    /// named file, configure the wrapper's stream input as ignored.
60    #[builder(field)]
61    pub other: Vec<String>,
62}
63
64impl<S: compiler_options_builder::State> CompilerOptionsBuilder<S> {
65    /// Appends one literal argument to [`CompilerOptions::other`], preserving order.
66    pub fn other(mut self, flag: impl Into<String>) -> Self {
67        self.other.push(flag.into());
68        self
69    }
70
71    /// Appends a present argument to [`CompilerOptions::other`]; `None` adds nothing.
72    pub fn maybe_other(mut self, flag: Option<impl Into<String>>) -> Self {
73        if let Some(flag) = flag {
74            self.other.push(flag.into());
75        }
76        self
77    }
78}