zlink_codegen/
lib.rs

1#![doc(
2    html_logo_url = "https://raw.githubusercontent.com/z-galaxy/zlink/3660d731d7de8f60c8d82e122b3ece15617185e4/data/logo.png"
3)]
4//! Code generation for Varlink interfaces.
5
6use anyhow::{Context, Result};
7use zlink::idl::Interface;
8
9mod codegen;
10pub use codegen::CodeGenerator;
11
12/// Generate Rust code from a Varlink interface.
13pub fn generate_interface(interface: &Interface<'_>) -> Result<String> {
14    let mut generator = CodeGenerator::new();
15    generator.generate_interface(interface, false)?;
16    Ok(generator.output())
17}
18
19/// Generate Rust code from multiple Varlink interfaces.
20pub fn generate_interfaces(interfaces: &[Interface<'_>]) -> Result<String> {
21    let mut generator = CodeGenerator::new();
22
23    // Add module-level header for multiple interfaces.
24    if interfaces.len() > 1 {
25        generator.write_module_header()?;
26    }
27
28    for interface in interfaces.iter() {
29        // Skip module header for all interfaces when generating multiple.
30        let skip_header = interfaces.len() > 1;
31        generator.generate_interface(interface, skip_header)?;
32    }
33    Ok(generator.output())
34}
35
36/// Format generated Rust code using rustfmt.
37pub fn format_code(code: &str) -> Result<String> {
38    use std::{
39        io::Write,
40        process::{Command, Stdio},
41    };
42
43    let mut child = Command::new("rustfmt")
44        .arg("--edition=2021")
45        .stdin(Stdio::piped())
46        .stdout(Stdio::piped())
47        .stderr(Stdio::piped())
48        .spawn()
49        .context("Failed to spawn rustfmt")?;
50
51    if let Some(mut stdin) = child.stdin.take() {
52        stdin
53            .write_all(code.as_bytes())
54            .context("Failed to write to rustfmt stdin")?;
55    }
56
57    let output = child
58        .wait_with_output()
59        .context("Failed to wait for rustfmt")?;
60
61    if !output.status.success() {
62        // If rustfmt fails, return the original code.
63        eprintln!(
64            "Warning: rustfmt failed: {}",
65            String::from_utf8_lossy(&output.stderr)
66        );
67        return Ok(code.to_string());
68    }
69
70    String::from_utf8(output.stdout).context("Failed to parse rustfmt output")
71}