///|
/// A safe, secret-free one-line summary of a protocol op, used by CLI
/// tooling and diagnostic output. Passwords and SASL payloads are never
/// included.
pub fn describe_op(op : ProtocolOp) -> String {
  match op {
    BindRequest(req) => {
      let auth = match req.authentication {
        Simple(_) => "simple"
        Sasl(creds) =>
          "sasl(" +
          redact_sasl_credentials(creds.mechanism, creds.credentials) +
          ")"
      }
      "bindRequest version=\{req.version} name=\{req.name} auth=\{auth}"
    }
    BindResponse(resp) =>
      "bindResponse resultCode=\{resp.result.result_code.to_string()}"
    UnbindRequest => "unbindRequest"
    SearchRequest(req) =>
      "searchRequest base=\{req.base_object} scope=\{req.scope.to_int()} filter=\{req.filter.to_string()}"
    SearchResultEntry(entry) =>
      "searchResultEntry dn=\{entry.object_name} attrs=\{entry.attributes.length()}"
    SearchResultDone(result) =>
      "searchResultDone resultCode=\{result.result_code.to_string()}"
    SearchResultReference(refs) =>
      "searchResultReference count=\{refs.uris.length()}"
    AbandonRequest(id) => "abandonRequest id=\{id}"
    ModifyRequest(req) =>
      "modifyRequest object=\{req.object} changes=\{req.changes.length()}"
    ModifyResponse(resp) =>
      "modifyResponse resultCode=\{resp.result.result_code.to_string()}"
    AddRequest(req) =>
      "addRequest entry=\{req.entry} attrs=\{req.attributes.length()}"
    AddResponse(resp) =>
      "addResponse resultCode=\{resp.result.result_code.to_string()}"
    DelRequest(req) => "delRequest entry=\{req.entry}"
    DelResponse(resp) =>
      "delResponse resultCode=\{resp.result.result_code.to_string()}"
    ModifyDnRequest(req) =>
      "modifyDNRequest entry=\{req.entry} newrdn=\{req.newrdn}"
    ModifyDnResponse(resp) =>
      "modifyDNResponse resultCode=\{resp.result.result_code.to_string()}"
    CompareRequest(req) =>
      "compareRequest entry=\{req.entry} attr=\{req.ava.attribute_desc}"
    CompareResponse(resp) =>
      "compareResponse resultCode=\{resp.result.result_code.to_string()}"
    ExtendedRequest(req) => "extendedReq name=\{req.request_name}"
    ExtendedResponse(resp) =>
      "extendedResp resultCode=\{resp.result.result_code.to_string()}"
  }
}