use proc_macro::TokenStream;
use syn::LitStr;
pub(super) fn guard_server_grpc_transport(
schema_path: &LitStr,
schema: &cratestack_core::Schema,
) -> Result<(), TokenStream> {
if !schema_declares_grpc_transport(schema) {
return Ok(());
}
if cfg!(feature = "grpc") {
return Ok(());
}
Err(TokenStream::from(
syn::Error::new(
schema_path.span(),
"schema declares `transport grpc`, but `cratestack-macros` was compiled without \
its `grpc` Cargo feature — enable it via \
`cratestack = { package = \"cratestack-pg\", features = [\"grpc\"] }` in your \
Cargo.toml. Without the feature, `cratestack generate-proto` can still emit this \
schema's `.proto` contract including its `service` block (tracking: \
https://github.com/cratestack/cratestack/issues/171).",
)
.to_compile_error(),
))
}
pub(super) fn guard_client_or_embedded_grpc_transport(
schema_path: &LitStr,
schema: &cratestack_core::Schema,
macro_name: &str,
) -> Result<(), TokenStream> {
if !schema_declares_grpc_transport(schema) {
return Ok(());
}
Err(TokenStream::from(
syn::Error::new(
schema_path.span(),
format!(
"schema declares `transport grpc`, but `{macro_name}!` has no gRPC codegen — \
only `include_server_schema!` does (behind its `grpc` Cargo feature). A Rust \
gRPC client generator and embedded-role gRPC support are not implemented and \
not currently tracked as a specific ticket; \
https://github.com/cratestack/cratestack/issues/172 covers the browser \
(gRPC-Web/TypeScript) client only, not a native Rust one. \
`cratestack generate-proto` can still emit this schema's `.proto` contract \
today for use with a non-CrateStack gRPC client.",
),
)
.to_compile_error(),
))
}
fn schema_declares_grpc_transport(schema: &cratestack_core::Schema) -> bool {
schema.transport == cratestack_core::TransportStyle::Grpc
}
#[cfg(test)]
mod tests {
use super::schema_declares_grpc_transport;
#[test]
fn flags_grpc_transport_schema() {
let schema = cratestack_parser::parse_schema(
r#"
transport grpc
model Widget {
id Int @id
}
"#,
)
.expect("schema should parse");
assert!(schema_declares_grpc_transport(&schema));
}
#[test]
fn does_not_flag_rest_transport_schema() {
let schema = cratestack_parser::parse_schema(
r#"
model Widget {
id Int @id
}
"#,
)
.expect("schema should parse");
assert!(!schema_declares_grpc_transport(&schema));
}
#[test]
fn does_not_flag_rpc_transport_schema() {
let schema = cratestack_parser::parse_schema(
r#"
transport rpc
model Widget {
id Int @id
}
"#,
)
.expect("schema should parse");
assert!(!schema_declares_grpc_transport(&schema));
}
}