status-im / nim-stew

stew is collection of utilities, std library extensions and budding libraries that are frequently used at Status, but are too small to deserve their own git repository.
133 stars 18 forks source link

allow customizing template name in `valueOr` / `errorOr` #174

Closed etan-status closed 1 year ago

etan-status commented 1 year ago

Currently, valueOr / errorOr support is degraded when used from a generic or template context, due to naming collision of the injected template and different precedence being applied in such contexts. To still allow using the functionality as expected, provide overloads that allow customizing the field names.

https://github.com/status-im/nim-stew/issues/161#issuecomment-1397121386

etan-status commented 1 year ago

Usage example:

proc decodeLightClientObjectHttpResponse[T: SomeForkedLightClientObject](
    resp: RestHttpResponseRef,
    data: Future[seq[byte]],
    cfg: RuntimeConfig,
    x: typedesc[T]): Future[T] {.async.} =
  let
    consensusFork = decodeEthConsensusVersion(
      resp.headers.getString("eth-consensus-version")).valueOr(resError):
        raiseRestDecodingBytesError(resError)
    mediaType = decodeMediaType(resp.contentType).valueOr(resError):
      raise newException(RestError, $resError)
    obj =
      if mediaType == OctetStreamMediaType:
        decodeBytes(T, await data, resp.contentType).valueOr(resError):
          raiseRestDecodingBytesError(resError)
      elif mediaType == ApplicationJsonMediaType:
        withLcDataFork(lcDataForkAtConsensusFork(consensusFork)):
          when lcDataFork > LightClientDataFork.None:
            var obj = T(kind: lcDataFork)
            obj.forky(lcDataFork) = SSZ.decode(
              await data, T.Forky(lcDataFork))
            obj
          else:
            raiseRestDecodingBytesError(
              cstring("Unsupported fork: " & $consensusFork))
      else:
        raise newException(RestError, "Unsupported content-type")
    objectFork = withForkyObject(obj):
      when lcDataFork > LightClientDataFork.None:
        cfg.consensusForkAtEpoch(forkyObject.contextEpoch)
      else:
        raiseRestDecodingBytesError("Invalid data")
  if consensusFork != objectFork:
    raiseRestDecodingBytesError(cstring("Inconsistent forks" &
      " (header: " & $consensusFork & ", data: " & $objectFork & ")"))
  return obj
etan-status commented 1 year ago

From nimbus-eth2 PM discussion 2023-03-22 it was suggested to work around this limitation in nimbus-eth2 instead of nim-stew.