forge_core/function/
traits.rs1use std::future::Future;
2use std::pin::Pin;
3
4use serde::{Serialize, de::DeserializeOwned};
5
6use super::context::{MutationContext, QueryContext};
7use crate::error::Result;
8
9#[derive(Debug, Clone)]
11pub struct FunctionInfo {
12 pub name: &'static str,
14 pub description: Option<&'static str>,
16 pub kind: FunctionKind,
18 pub required_role: Option<&'static str>,
20 pub is_public: bool,
22 pub cache_ttl: Option<u64>,
24 pub timeout: Option<u64>,
26 pub rate_limit_requests: Option<u32>,
28 pub rate_limit_per_secs: Option<u64>,
30 pub rate_limit_key: Option<&'static str>,
32 pub log_level: Option<&'static str>,
35 pub table_dependencies: &'static [&'static str],
38 pub transactional: bool,
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46pub enum FunctionKind {
47 Query,
48 Mutation,
49}
50
51impl std::fmt::Display for FunctionKind {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 match self {
54 FunctionKind::Query => write!(f, "query"),
55 FunctionKind::Mutation => write!(f, "mutation"),
56 }
57 }
58}
59
60pub trait ForgeQuery: Send + Sync + 'static {
69 type Args: DeserializeOwned + Serialize + Send + Sync;
71 type Output: Serialize + Send;
73
74 fn info() -> FunctionInfo;
76
77 fn execute(
79 ctx: &QueryContext,
80 args: Self::Args,
81 ) -> Pin<Box<dyn Future<Output = Result<Self::Output>> + Send + '_>>;
82}
83
84pub trait ForgeMutation: Send + Sync + 'static {
92 type Args: DeserializeOwned + Serialize + Send + Sync;
94 type Output: Serialize + Send;
96
97 fn info() -> FunctionInfo;
99
100 fn execute(
102 ctx: &MutationContext,
103 args: Self::Args,
104 ) -> Pin<Box<dyn Future<Output = Result<Self::Output>> + Send + '_>>;
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_function_kind_display() {
113 assert_eq!(format!("{}", FunctionKind::Query), "query");
114 assert_eq!(format!("{}", FunctionKind::Mutation), "mutation");
115 }
116
117 #[test]
118 fn test_function_info() {
119 let info = FunctionInfo {
120 name: "get_user",
121 description: Some("Get a user by ID"),
122 kind: FunctionKind::Query,
123 required_role: None,
124 is_public: false,
125 cache_ttl: Some(300),
126 timeout: Some(30),
127 rate_limit_requests: Some(100),
128 rate_limit_per_secs: Some(60),
129 rate_limit_key: Some("user"),
130 log_level: Some("debug"),
131 table_dependencies: &["users"],
132 transactional: false,
133 };
134
135 assert_eq!(info.name, "get_user");
136 assert_eq!(info.kind, FunctionKind::Query);
137 assert_eq!(info.cache_ttl, Some(300));
138 assert_eq!(info.rate_limit_requests, Some(100));
139 assert_eq!(info.log_level, Some("debug"));
140 assert_eq!(info.table_dependencies, &["users"]);
141 }
142}