docs: def decode_complex_ops(encoded_querystring, operators=None, negation=True):
      """
      Returns a list of (querystring, negate, op) tuples that represent complex operations.
      This function will raise a `ValidationError`s if:
      - the individual querystrings are not wrapped in parentheses
      - the set operators do not match the provided `operators`
      - there is trailing content after the ending querysting
      Ex::
          # unencoded query: (a=1) & (b=2) | ~(c=3)
          >>> s = '%28a%253D1%29%20%26%20%28b%253D2%29%20%7C%20%7E%28c%253D3%29'
          >>> decode_querystring_ops(s)
          [
              ('a=1', False, QuerySet.__and__),
              ('b=2', False, QuerySet.__or__),
              ('c=3', True, None),
          ]
      """
      complex_op_re = COMPLEX_OP_NEG_RE if negation else COMPLEX_OP_RE
      if operators is None:
          operators = COMPLEX_OPERATORS
  
      # decode into: (a%3D1) & (b%3D2) | ~(c%3D3)
      decoded_querystring = unquote(encoded_querystring)
      matches = [m for m in complex_op_re.finditer(decoded_querystring)]
  
      if not matches:
          msg = _("Unable to parse querystring. Decoded: '%(decoded)s'.")
          raise SerializerValidationError(msg % {'decoded': decoded_querystring})
  
      results, errors = [], []
      for match, has_next in lookahead(matches):
          negate, querystring, op = match.groups()
  
          negate = negate == '~'
          querystring = unquote(querystring)
          op_func = operators.get(op.strip()) if op else None
          if op_func is None and has_next:
              msg = _("Invalid querystring operator. Matched: '%(op)s'.")
              errors.append(msg % {'op': op})
  
          results.append(ComplexOp(querystring, negate, op_func))
  
      trailing_chars = decoded_querystring[matches[-1].end():]
      if trailing_chars:
          msg = _("Ending querystring must not have trailing characters. Matched: '%(chars)s'.")
          errors.append(msg % {'chars': trailing_chars})
  
      if errors:
          raise SerializerValidationError(errors)
  
      return results