iocaine 1.0.0

The deadliest poison known to AI
Documentation
// SPDX-FileCopyrightText: 2025 Gergely Nagy
// SPDX-FileContributor: Gergely Nagy
//
// SPDX-License-Identifier: MIT

use regex::Regex;
use serde::Deserialize;

#[derive(Clone, Debug, Deserialize)]
pub struct Config {
    #[serde(default)]
    pub server: ServerConfig,
    pub sources: SourceConfig,
    #[serde(default)]
    pub generator: GeneratorConfig,
    #[serde(default)]
    pub templates: TemplatesConfig,
    #[serde(default)]
    pub metrics: MetricsConfig,
}

#[derive(Clone, Debug, Deserialize, Default)]
pub struct ServerConfig {
    #[serde(default = "ServerConfig::default_bind")]
    pub bind: String,
}

#[derive(Clone, Debug, Deserialize, Default)]
pub struct MetricsConfig {
    #[serde(default)]
    pub enable: bool,
    #[serde(default)]
    pub labels: Vec<MetricsLabel>,
    #[serde(default = "MetricsConfig::default_bind")]
    pub bind: String,
    #[serde(default)]
    pub agent_group: Vec<AgentGroupConfig>,
}

impl MetricsConfig {
    fn default_bind() -> String {
        "127.0.0.1:42042".to_string()
    }
}

#[derive(Clone, Debug, Deserialize, PartialEq)]
pub enum MetricsLabel {
    Host,
    UserAgent,
    UserAgentGroup,
}

#[derive(Clone, Debug, Deserialize)]
pub struct AgentGroupConfig {
    #[serde(with = "serde_regex")]
    pub agent: Regex,
    pub group: String,
}

impl ServerConfig {
    fn default_bind() -> String {
        "127.0.0.1:42069".to_string()
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct SourceConfig {
    pub markov: Vec<String>,
    pub words: String,
}

#[derive(Clone, Debug, Deserialize, Default)]
pub struct GeneratorConfig {
    #[serde(default)]
    pub markov: MarkovGeneratorConfig,
    #[serde(default)]
    pub links: LinkGeneratorConfig,
    #[serde(default)]
    pub initial_seed: String,
}

#[derive(Clone, Debug, Deserialize, Default)]
pub struct MarkovGeneratorConfig {
    #[serde(default)]
    pub paragraphs: MarkovParagraphsConfig,
    #[serde(default)]
    pub words: MarkovWordsConfig,
}

#[derive(Clone, Debug, Deserialize)]
pub struct MarkovParagraphsConfig {
    #[serde(default = "MarkovParagraphsConfig::default_min")]
    pub min: u32,
    #[serde(default = "MarkovParagraphsConfig::default_max")]
    pub max: u32,
}

impl Default for MarkovParagraphsConfig {
    fn default() -> Self {
        Self {
            min: Self::default_min(),
            max: Self::default_max(),
        }
    }
}

impl MarkovParagraphsConfig {
    fn default_min() -> u32 {
        1
    }
    fn default_max() -> u32 {
        1
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct MarkovWordsConfig {
    #[serde(default = "MarkovWordsConfig::default_min")]
    pub min: u32,
    #[serde(default = "MarkovWordsConfig::default_max")]
    pub max: u32,
}

impl Default for MarkovWordsConfig {
    fn default() -> Self {
        Self {
            min: Self::default_min(),
            max: Self::default_max(),
        }
    }
}

impl MarkovWordsConfig {
    fn default_min() -> u32 {
        10
    }
    fn default_max() -> u32 {
        420
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct LinkGeneratorConfig {
    #[serde(default = "LinkGeneratorConfig::default_min")]
    pub min: u32,
    #[serde(default = "LinkGeneratorConfig::default_max")]
    pub max: u32,
    #[serde(default)]
    pub href_words: LinkGeneratorHrefWordsConfig,
    #[serde(default)]
    pub title_words: LinkGeneratorTitleWordsConfig,
}

impl Default for LinkGeneratorConfig {
    fn default() -> Self {
        Self {
            min: Self::default_min(),
            max: Self::default_max(),
            href_words: LinkGeneratorHrefWordsConfig::default(),
            title_words: LinkGeneratorTitleWordsConfig::default(),
        }
    }
}

impl LinkGeneratorConfig {
    fn default_min() -> u32 {
        2
    }
    fn default_max() -> u32 {
        5
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct LinkGeneratorHrefWordsConfig {
    #[serde(default = "LinkGeneratorHrefWordsConfig::default_min")]
    pub min: u32,
    #[serde(default = "LinkGeneratorHrefWordsConfig::default_max")]
    pub max: u32,
}

impl Default for LinkGeneratorHrefWordsConfig {
    fn default() -> Self {
        Self {
            min: Self::default_min(),
            max: Self::default_max(),
        }
    }
}

impl LinkGeneratorHrefWordsConfig {
    fn default_min() -> u32 {
        1
    }
    fn default_max() -> u32 {
        2
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct LinkGeneratorTitleWordsConfig {
    #[serde(default = "LinkGeneratorTitleWordsConfig::default_min")]
    pub min: u32,
    #[serde(default = "LinkGeneratorTitleWordsConfig::default_max")]
    pub max: u32,
}

impl Default for LinkGeneratorTitleWordsConfig {
    fn default() -> Self {
        Self {
            min: Self::default_min(),
            max: Self::default_max(),
        }
    }
}

impl LinkGeneratorTitleWordsConfig {
    fn default_min() -> u32 {
        4
    }
    fn default_max() -> u32 {
        8
    }
}

#[derive(Clone, Debug, Deserialize, Default)]
pub struct TemplatesConfig {
    pub directory: Option<String>,
}