Actus 1.5.0
Fixed
-
A declared
boolroute-parameter default was unreachable. Every typed
parameter reaches its default through the generated
get_x(name).unwrap_or(default), which works becauseget_xreturnsErr
on a missing parameter.boolis the one type whose absence is itself a
usable value, soget_boolansweredOk(false)rather than erroring —
unwrap_orunwrapped thatfalseand the default was dead code. Every
param: bool = truesilently behaved asfalse. Found in a consumer: a
cancellation route declaringat_period_end: bool = truecancelled
immediately when the client omitted the parameter — the destructive
direction, and the opposite of what the route documented. It stayed invisible
because the route behaved correctly whenever the parameter was supplied.A bare
param: boolis unchanged — it is required, and a request
omitting it gets a400, exactly as a bareStringoru64does. (An
earlier draft of this entry said a bareboolreadsfalsewhen absent.
That was wrong and unverified:routing::resolverejects it before
extraction. An optional flag is spelledconfirm: bool = false.) -
ExtractedParams::get_boolnow returns400when the parameter is absent,
asget_string,get_i64and every other scalar getter already did. It was
the one getter that invented a value —Ok(false)— instead of erroring, and
that invented value is what made a declaredbooldefault unreachable.Not a breaking change, despite being a behaviour change to a public
method:ExtractedParamshas private fields and no public constructor, so
routing::resolveis the only way to obtain one, and it rejects an absent
bareboolbefore this method can be reached. The branch was unreachable from
outside the crate. Useget_bool_optionalto tell absence from an explicit
false.
Added
-
ExtractedParams::get_bool_optional— distinguishes an absent bool
parameter (None) from one supplied asfalse, which is the reader a
declared default needs. MirrorsParams::get_bool_optionalon the
pre-resolution type. -
routing::param_is_required(&ParamDef), re-exported at
actus::routing: whether an absent value for a parameter makes the request a
400— the rulerouting::resolveenforces, exported so a tool reporting
requiredness cannot disagree with the router. The OpenAPI generator's
requiredflag now calls it instead of re-deriving the same expression in a
second crate, where the two agreed only by diligence and would have diverged
the first time a new inherently-optional type was added.The rule it fixes in one place: a query parameter is required unless it
declared a default, uniformly across every scalar type, so requiredness is
readable off aroutes!block without knowing the type.ParamType::StringArray
is the sole exemption, and a forced one — urlencoding cannot express "present
but empty", so no distinction is available to lose.boolis deliberately not
exempt: exempting it would leave no way to declare a required bool, and would
discard a distinction the wire does carry.