a few small ones that don't each deserve their own issue. all independently fixable.
missing content-type silently skips the body
crates/tonneau/src/private/http/body.rs:24:
let Some(content_type) = parts.headers.get(http::header::CONTENT_TYPE) else {
return Ok(());
};
if you post a json body but forget the content-type header, deserialization is skipped entirely and the handler gets a default-initialized message. the caller then sees confusing "missing field" validation errors instead of something telling them what's actually wrong. note a wrong content-type is already rejected properly at body.rs:46, it's only the missing case that falls through.
UInt64Constraints.gt is an int64
crates/tonneau/annotations.proto:458:
message UInt64Constraints {
oneof greater {
// Requires the input value is greater than the value provided.
int64 gt = 1 [(predefined).cel = {
gte, lt, lte and friends in the same message are all uint64. as is, you can't express a lower bound above i64::MAX. same wire tag either way so it should be a quiet fix.
error envelope code doesn't match the docs
the readme and crates/tonneau/src/lib.rs both show error responses carrying the numeric grpc code:
{ "code": 3, "message": "bad request" }
but the impl serializes the http status as a string, crates/tonneau/src/private/error.rs:459:
self.to_http_status().as_str().serialize(serializer)
so what actually goes over the wire is "code": "400". pick one and align the other. imo the grpc code is the more useful of the two (the http status is already on the response line), but either way docs and code should agree.
a few small ones that don't each deserve their own issue. all independently fixable.
missing content-type silently skips the body
crates/tonneau/src/private/http/body.rs:24:if you post a json body but forget the
content-typeheader, deserialization is skipped entirely and the handler gets a default-initialized message. the caller then sees confusing "missing field" validation errors instead of something telling them what's actually wrong. note a wrong content-type is already rejected properly atbody.rs:46, it's only the missing case that falls through.UInt64Constraints.gtis anint64crates/tonneau/annotations.proto:458:gte,lt,lteand friends in the same message are alluint64. as is, you can't express a lower bound abovei64::MAX. same wire tag either way so it should be a quiet fix.uint64error envelope
codedoesn't match the docsthe readme and
crates/tonneau/src/lib.rsboth show error responses carrying the numeric grpc code:{ "code": 3, "message": "bad request" }but the impl serializes the http status as a string,
crates/tonneau/src/private/error.rs:459:so what actually goes over the wire is
"code": "400". pick one and align the other. imo the grpc code is the more useful of the two (the http status is already on the response line), but either way docs and code should agree.