Rust宏编程与3D建模工具库kittycad-modeling-cmds-macros-impl的使用,实现高效命令生成与解析

以下是关于Rust宏编程与kittycad-modeling-cmds-macros-impl库的使用内容:

安装

在项目目录中运行以下Cargo命令:

cargo add kittycad-modeling-cmds-macros-impl

或在Cargo.toml中添加:

kittycad-modeling-cmds-macros-impl = "0.1.13"

使用示例

kittycad-modeling-cmds-macros-impl是一个用于3D建模命令生成与解析的Rust宏实现库。以下是一个完整的使用示例:

use kittycad_modeling_cmds_macros_impl::command_macro;

// 定义一个3D建模命令结构体
#[command_macro]
struct CreateCube {
    size: f64,
    center: bool,
}

fn main() {
    // 使用宏生成的代码创建立方体命令
    let cube_cmd = CreateCube {
        size: 10.0,
        center: true,
    };

    // 序列化为JSON命令字符串
    let json_cmd = cube_cmd.to_json();
    println!("Generated command: {}", json_cmd);

    // 解析JSON命令
    let parsed_cmd = CreateCube::from_json(&json_cmd).unwrap();
    assert_eq!(parsed_cmd.size, 10.0);
    assert_eq!(parsed_cmd.center, true);
}

功能说明

  1. #[command_macro]宏会自动为结构体生成:

    • to_json()方法:将命令序列化为JSON字符串
    • from_json()方法:从JSON字符串解析命令
    • 必要的trait实现(Serialize/Deserialize等)
  2. 该库主要用于KittyCAD的3D建模API命令系统,可以高效地:

    • 生成3D建模命令
    • 解析API响应
    • 验证命令参数

完整示例

下面是一个更完整的示例,展示了如何定义多个3D建模命令并使用它们:

use kittycad_modeling_cmds_macros_impl::command_macro;

// 定义立方体命令
#[command_macro]
struct CreateCube {
    size: f64,
    center: bool,
}

// 定义球体命令
#[command_macro]
struct CreateSphere {
    radius: f64,
    segments: u32,
}

fn main() {
    // 创建立方体命令
    let cube = CreateCube {
        size: 5.0,
        center: false,
    };
    
    // 创建球体命令
    let sphere = CreateSphere {
        radius: 3.0,
        segments: 32,
    };

    // 序列化为JSON
    let cube_json = cube.to_json();
    let sphere_json = sphere.to_json();

    println!("Cube command: {}", cube_json);
    println!("Sphere command: {}", sphere_json);

    // 从JSON解析
    let parsed_cube = CreateCube::from_json(&cube_json).unwrap();
    let parsed_sphere = CreateSphere::from_json(&sphere_json).unwrap();

    assert_eq!(parsed_cube.size, 5.0);
    assert_eq!(parsed_sphere.radius, 3.0);
}

许可证

MIT License

注意:此库是KittyCAD建模API的一部分,主要用于内部命令系统,但也可以用于其他需要结构化命令生成与解析的场景。


1 回复

Rust宏编程与3D建模工具库kittycad-modeling-cmds-macros-impl的使用

概述

kittycad-modeling-cmds-macros-impl是一个用于3D建模命令生成与解析的Rust宏库,它利用Rust强大的宏系统来简化3D建模命令的创建和处理流程。这个库特别适合需要高效生成和解析复杂3D建模命令的场景。

主要功能

  1. 通过宏自动生成3D建模命令结构体
  2. 提供命令序列化与反序列化支持
  3. 简化命令参数验证
  4. 生成命令执行逻辑

安装方法

在Cargo.toml中添加依赖:

[dependencies]
kittycad-modeling-cmds-macros-impl = "0.1"

基本使用方法

1. 定义命令

use kittycad_modeling_cmds_macros_impl::command;

#[command]
struct CreateCube {
    #[param]
    size: f64,
    #[param]
    center: bool,
}

宏会自动生成:

  • 命令结构体
  • 参数验证逻辑
  • 序列化/反序列化实现
  • 命令执行trait实现

2. 使用生成的命令

let cmd = CreateCube {
    size: 10.0,
    center: true,
};

// 序列化为JSON
let json = serde_json::to_string(&cmd)?;

// 从JSON反序列化
let cmd: CreateCube = serde_json::from_str(&json)?;

// 执行命令
let result = cmd.execute(&mut modeling_engine)?;

高级用法

命令组合

#[command]
struct CompositeCommand {
    #[subcommand]
    commands: Vec<Box<dyn ModelingCommand>>,
}

自定义参数验证

#[command]
struct CreateSphere {
    #[param(validate = "validate_radius")]
    radius: f64,
}

fn validate_radius(radius: f64) -> Result<(), String> {
    if radius <= 0.0 {
        Err("Radius must be positive".to_string())
    } else {
        Ok(())
    }
}

异步命令执行

#[command]
#[async_trait]
struct AsyncCommand {
    #[param]
    data: String,
}

#[async_trait]
impl ModelingCommand for AsyncCommand {
    async fn execute(&self, engine: &mut ModelingEngine) -> Result<(), ModelingError> {
        // 异步执行逻辑
        Ok(())
    }
}

实际示例:创建复杂3D模型

#[command]
struct CreateTable {
    #[param]
    width: f64,
    #[param]
    height: f64,
    #[param]
    depth: f64,
    #[param]
    leg_thickness: f64,
}

impl CreateTable {
    fn execute(&self, engine: &mut ModelingEngine) -> Result<(), ModelingError> {
        // 创建桌面
        engine.create_cube(self.width, self.height, self.depth)?;
        
        // 创建四条腿
        let leg_positions = [
            (self.leg_thickness/2.0, self.leg_thickness/2.0, 0.0),
            (self.width - self.leg_thickness/2.0, self.leg_thickness/2.0, 0.0),
            (self.leg_thickness/2.0, self.depth - self.leg_thickness/2.0, 0.0),
            (self.width - self.leg_thickness/2.0, self.depth - self.leg_thickness/2.0, 0.0),
        ];
        
        for (x, y, _) in leg_positions {
            engine.create_cylinder(
                x, y, -self.height, 
                self.leg_thickness/2.0, 
                self.height
            )?;
        }
        
        Ok(())
    }
}

完整示例代码

use kittycad_modeling_cmds_macros_impl::command;
use serde::{Serialize, Deserialize};
use async_trait::async_trait;

// 定义基本命令
#[command]
#[derive(Debug, Serialize, Deserialize)]
struct CreateCube {
    #[param]
    size: f64,
    #[param]
    center: bool,
}

// 定义带验证的命令
#[command]
#[derive(Debug)]
struct CreateSphere {
    #[param(validate = "validate_radius")]
    radius: f64,
}

fn validate_radius(radius: f64) -> Result<(), String> {
    if radius <= 0.0 {
        Err("Radius must be positive".into())
    } else {
        Ok(())
    }
}

// 定义异步命令
#[command]
#[async_trait]
#[derive(Debug)]
struct AsyncRender {
    #[param]
    quality: u32,
}

#[async_trait]
impl ModelingCommand for AsyncRender {
    async fn execute(&self, engine: &mut ModelingEngine) -> Result<(), ModelingError> {
        // 模拟异步渲染
        tokio::time::sleep(std::time::Duration::from_secs(1)).await;
        println!("Rendering with quality: {}", self.quality);
        Ok(())
    }
}

// 定义复合命令
#[command]
#[derive(Debug)]
struct Scene {
    #[subcommand]
    objects: Vec<Box<dyn ModelingCommand>>,
}

// 使用示例
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化建模引擎
    let mut engine = ModelingEngine::new();
    
    // 创建简单立方体
    let cube = CreateCube {
        size: 5.0,
        center: true,
    };
    cube.execute(&mut engine)?;
    
    // 创建带验证的球体
    let sphere = CreateSphere { radius: 2.5 };
    sphere.execute(&mut engine)?;
    
    // 执行异步命令
    let render = AsyncRender { quality: 100 };
    render.execute(&mut engine).await?;
    
    // 创建复合场景
    let scene = Scene {
        objects: vec![
            Box::new(CreateCube { size: 1.0, center: false }),
            Box::new(CreateSphere { radius: 0.5 }),
        ],
    };
    scene.execute(&mut engine)?;
    
    Ok(())
}

最佳实践

  1. 为复杂命令定义清晰的参数验证逻辑
  2. 将常用命令组合成复合命令
  3. 利用宏生成的序列化功能实现命令持久化
  4. 为性能关键路径的命令实现缓存机制

性能考虑

  • 宏展开在编译时完成,运行时无额外开销
  • 生成的代码经过优化,与手写代码性能相当
  • 对于大量命令处理,考虑使用命令批处理模式

通过合理使用kittycad-modeling-cmds-macros-impl库,可以显著提高3D建模应用的开发效率和运行性能。

回到顶部