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}