atomfn 0.1.0

AtomService 函数服务 Rust SDK:与 TS SDK 协议一致的常驻 HTTP 运行时
Documentation
//! AtomService 函数服务 Rust SDK。
//!
//! 提供与 TypeScript SDK 协议一致的常驻 HTTP 运行时:
//! `POST /invoke/<function>`、`GET /__health`、统一错误信封与 SSE 流式。
//!
//! # 示例
//!
//! ```no_run
//! use atomfn::{serve, Ctx, FunctionError};
//! use serde::{Deserialize, Serialize};
//!
//! #[derive(Deserialize)]
//! struct Input { name: String }
//!
//! #[derive(Serialize)]
//! struct Output { greeting: String }
//!
//! fn greet(input: Input, ctx: &Ctx) -> Result<Output, FunctionError> {
//!     ctx.info("greeting");
//!     Ok(Output { greeting: format!("hi {}", input.name) })
//! }
//!
//! serve! { greet }
//! ```

mod context;
mod registry;
mod serve;

pub use context::{generate_request_id, Ctx, FunctionError};
pub use registry::{Outcome, Registry, StreamItems};
pub use serve::serve;

/// 声明函数注册表并启动 HTTP 运行时。
///
/// 普通函数直接写函数名,流式函数前加 `stream` 关键字。
///
/// # 示例
///
/// ```ignore
/// serve! {
///     greet,
///     add,
///     stream tick,
/// }
/// ```
///
/// 展开为:
///
/// ```ignore
/// fn main() {
///     let mut registry = atomfn::Registry::new();
///     registry.function("greet", greet);
///     registry.function("add", add);
///     registry.stream_function("tick", tick);
///     atomfn::serve(registry);
/// }
/// ```
#[macro_export]
macro_rules! serve {
    // 内部递归:处理 stream 条目
    (@register $registry:ident, stream $name:ident, $($rest:tt)*) => {
        $registry.stream_function(stringify!($name), $name);
        $crate::serve!(@register $registry, $($rest)*);
    };
    // 内部递归:处理普通条目
    (@register $registry:ident, $name:ident, $($rest:tt)*) => {
        $registry.function(stringify!($name), $name);
        $crate::serve!(@register $registry, $($rest)*);
    };
    // 内部递归:处理末尾 stream 条目(无尾逗号)
    (@register $registry:ident, stream $name:ident) => {
        $registry.stream_function(stringify!($name), $name);
    };
    // 内部递归:处理末尾条目(无尾逗号)
    (@register $registry:ident, $name:ident) => {
        $registry.function(stringify!($name), $name);
    };
    // 内部递归:终止
    (@register $registry:ident,) => {};
    (@register $registry:ident) => {};
    // 入口:生成 main 函数
    ( $($tokens:tt)+ ) => {
        fn main() {
            let mut registry = $crate::Registry::new();
            $crate::serve!(@register registry, $($tokens)+);
            $crate::serve(registry);
        }
    };
}