iocaine 2.1.0

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

use base64::{engine::general_purpose::STANDARD, Engine as _};
use image::Luma;
use minijinja::{
    value::{Kwargs, ViaDeserialize},
    Error, State,
};
use qrcode::{render::svg, QrCode};
use serde::Deserialize;
use std::io::Cursor;

#[derive(Debug, Deserialize, PartialEq)]
enum QRFormat {
    #[serde(rename = "png")]
    Png,
    #[serde(rename = "svg")]
    Svg,
    #[serde(rename = "svg:raw")]
    SvgRaw,
}

pub fn generate(_state: &State, content: String, options: Kwargs) -> Result<String, Error> {
    let format = options
        .get::<Option<ViaDeserialize<QRFormat>>>("format")?
        .unwrap_or(ViaDeserialize(QRFormat::Png))
        .0;
    let width: Option<usize> = options.get("width")?;
    let height: Option<usize> = options.get("height")?;

    let code = QrCode::new(content.as_bytes()).unwrap();

    match format {
        QRFormat::Png => {
            let image = if let (Some(w), Some(h)) = (width, height) {
                code.render::<Luma<u8>>()
                    .max_dimensions(w as u32, h as u32)
                    .build()
            } else {
                code.render::<Luma<u8>>().build()
            };

            let mut w: Vec<u8> = Vec::new();
            image
                .write_to(&mut Cursor::new(&mut w), image::ImageFormat::Png)
                .unwrap();

            let image_data = STANDARD.encode(w);
            Ok(format!("data:image/png;base64,{}", image_data))
        }
        QRFormat::Svg | QRFormat::SvgRaw => {
            let image = if let (Some(w), Some(h)) = (width, height) {
                code.render()
                    .max_dimensions(w as u32, h as u32)
                    .dark_color(svg::Color("#000000"))
                    .light_color(svg::Color("#ffffff"))
                    .build()
            } else {
                code.render()
                    .dark_color(svg::Color("#000000"))
                    .light_color(svg::Color("#ffffff"))
                    .build()
            };

            if format == QRFormat::Svg {
                let image_data = STANDARD.encode(image);
                Ok(format!("data:image/svg+xml;base64,{}", image_data))
            } else {
                Ok(String::from_utf8(image.into()).unwrap())
            }
        }
    }
}