Skip to main content

optional_arg

Function optional_arg 

Source
pub fn optional_arg<T>(
    args: &mut Map<String, Value>,
    name: &str,
    invalid_arguments_with: impl FnOnce() -> JmapError,
) -> Result<Option<T>, JmapError>
Expand description

Extract an optional, deserializable argument from a method-arguments envelope (bd:JMAP-wlip.32).

Looks up name in args, removing it. The result is:

  • Ok(None) if the key is absent OR is present with Value::Null (RFC 8620 §3.3 treats absent and explicit-null the same for optional fields).
  • Ok(Some(value)) if the key is present and the value deserializes successfully into T.
  • Err(invalid_arguments_with(name)) if the value is present but fails to deserialize. The error message is built by the caller- supplied invalid_arguments_with so the resulting JmapError carries a domain-specific description (“ids must be an Id array”, “filter must be a Filter object”, etc.).

Collapses six near-identical match args.remove(...).unwrap_or(Value::Null) { Value::Null => None, v => Some(serde_json::from_value(v)...) } blocks in handlers.rs into one-liners.

§Interaction with ResultReference resolution (bd:JMAP-jfia.15)

crate::parse::resolve_args replaces a #key with the value produced by walking the JSON Pointer path against a prior response. RFC 6901 §4 makes no distinction between “key absent” and “key present with null”, so the resolved value CAN be Value::Null. This function then treats that resolved-null identically to “key was not sent”. The behaviour is RFC-compliant — both are “optional argument not provided” — but the asymmetry between an explicit null argument and a #key-resolved null argument may surprise a handler author who expects “I asked for the value via a ResultReference, so it must have been there”. If a handler needs to distinguish resolved-null from unsent, it has to read the raw args map before calling this helper.