Skip to main content

brief/
config.rs

1use crate::shortcode::{Registry, Shortcode};
2use serde::Deserialize;
3use std::collections::BTreeMap;
4use std::path::Path;
5
6#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq)]
7pub struct Config {
8    #[serde(default)]
9    pub project: Project,
10    #[serde(default)]
11    pub compile: Compile,
12    #[serde(default)]
13    pub shortcodes: BTreeMap<String, Shortcode>,
14    #[serde(default)]
15    pub hooks: Hooks,
16}
17
18#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq)]
19pub struct Project {
20    #[serde(default)]
21    pub name: String,
22    #[serde(default)]
23    pub version: String,
24}
25
26#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq)]
27pub struct Compile {
28    #[serde(default)]
29    pub strict_heading_levels: bool,
30    #[serde(default)]
31    pub default_target: Option<String>,
32    #[serde(default)]
33    pub llm: LlmCompile,
34}
35
36#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
37pub struct LlmCompile {
38    /// Master switch. When false, code blocks are emitted verbatim regardless
39    /// of language tag or `@minify` attribute.
40    #[serde(default = "default_minify_code_blocks")]
41    pub minify_code_blocks: bool,
42    /// Allowlist of language tags eligible for minification. Tags are
43    /// matched case-insensitively. Defaults to the v0.2 set.
44    #[serde(default = "default_minify_languages")]
45    pub minify_languages: Vec<String>,
46    /// Whether to keep the surrounding ```lang fence around minified code.
47    /// True (default) preserves the structural cue for the consumer LLM.
48    #[serde(default = "default_preserve_code_fences")]
49    pub preserve_code_fences: bool,
50}
51
52impl Default for LlmCompile {
53    fn default() -> Self {
54        LlmCompile {
55            minify_code_blocks: default_minify_code_blocks(),
56            minify_languages: default_minify_languages(),
57            preserve_code_fences: default_preserve_code_fences(),
58        }
59    }
60}
61
62fn default_minify_code_blocks() -> bool {
63    true
64}
65fn default_minify_languages() -> Vec<String> {
66    // v0.3 ships minifiers for JSON/JSONL plus the C-family + SQL set.
67    // Aliases are listed explicitly so a user pruning the list by tag name
68    // doesn't accidentally lose a language.
69    vec![
70        "json".into(),
71        "jsonl".into(),
72        "rust".into(),
73        "rs".into(),
74        "c".into(),
75        "h".into(),
76        "cpp".into(),
77        "c++".into(),
78        "cc".into(),
79        "cxx".into(),
80        "hpp".into(),
81        "hxx".into(),
82        "java".into(),
83        "go".into(),
84        "javascript".into(),
85        "js".into(),
86        "typescript".into(),
87        "ts".into(),
88        "sql".into(),
89    ]
90}
91fn default_preserve_code_fences() -> bool {
92    true
93}
94
95#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq)]
96pub struct Hooks {
97    #[serde(default)]
98    pub before_compile: Vec<String>,
99    #[serde(default)]
100    pub after_compile: Vec<String>,
101}
102
103pub fn load(path: &Path) -> Result<Config, String> {
104    let text = std::fs::read_to_string(path).map_err(|e| e.to_string())?;
105    toml::from_str(&text).map_err(|e| e.to_string())
106}
107
108pub fn registry_from(cfg: &Config) -> Registry {
109    let mut reg = Registry::with_builtins();
110    reg.extend(cfg.shortcodes.clone());
111    reg
112}