# flare.grpc.status

> A module of flare_mlake's API.

``gRPC`` status codes and trailer carrier.

A gRPC call ends with a *trailer* header set containing at least
``grpc-status`` (a decimal integer 0..16). Successful calls
return ``grpc-status: 0`` (OK); failed calls return a non-zero
code plus an optional ``grpc-message`` (a Percent-Encoded UTF-8
human description, capped at a few KiB by most clients).

This module defines the 16 standard status code constants and a
small :class:`GrpcStatus` carrier callers can pass through their
handler chain. The actual trailer-emitting code lives in the
HTTP/2 server adapter (a later commit); this module is purely
the data model.

References:
- https://github.com/grpc/grpc/blob/master/doc/statuscodes.md
- https://grpc.github.io/grpc/core/md_doc_statuscodes.html

## Structs

### `GrpcStatus`

```mojo
struct GrpcStatus
```

An RPC outcome: numeric code + optional human message + optional binary detail.

Status codes are stable across implementations -- a Mojo
handler returning ``GRPC_STATUS_NOT_FOUND`` will surface as
the same code in a Go / Python / C++ client. The optional
``message`` carries free-text context for diagnostics; it
must not be used for branching by the client.

``details`` carries the optional ``grpc-status-details-bin``
payload (RFC 4648 §4 base64 on the wire; opaque bytes here so
the application can attach a serialised
``google.rpc.Status`` proto, a typed error envelope, or any
other binary frame the client knows how to parse).

Implements: `Copyable`, `Movable`

Fields:

- `code: Int`
- `message: String`
- `details: Optional[List[UInt8]]`

#### `OK`

```mojo
comptime OK = Int(0)
```

#### `CANCELLED`

```mojo
comptime CANCELLED = Int(1)
```

#### `UNKNOWN`

```mojo
comptime UNKNOWN = Int(2)
```

#### `INVALID_ARGUMENT`

```mojo
comptime INVALID_ARGUMENT = Int(3)
```

#### `DEADLINE_EXCEEDED`

```mojo
comptime DEADLINE_EXCEEDED = Int(4)
```

#### `NOT_FOUND`

```mojo
comptime NOT_FOUND = Int(5)
```

#### `ALREADY_EXISTS`

```mojo
comptime ALREADY_EXISTS = Int(6)
```

#### `PERMISSION_DENIED`

```mojo
comptime PERMISSION_DENIED = Int(7)
```

#### `RESOURCE_EXHAUSTED`

```mojo
comptime RESOURCE_EXHAUSTED = Int(8)
```

#### `FAILED_PRECONDITION`

```mojo
comptime FAILED_PRECONDITION = Int(9)
```

#### `ABORTED`

```mojo
comptime ABORTED = Int(10)
```

#### `OUT_OF_RANGE`

```mojo
comptime OUT_OF_RANGE = Int(11)
```

#### `UNIMPLEMENTED`

```mojo
comptime UNIMPLEMENTED = Int(12)
```

#### `INTERNAL`

```mojo
comptime INTERNAL = Int(13)
```

#### `UNAVAILABLE`

```mojo
comptime UNAVAILABLE = Int(14)
```

#### `DATA_LOSS`

```mojo
comptime DATA_LOSS = Int(15)
```

#### `UNAUTHENTICATED`

```mojo
comptime UNAUTHENTICATED = Int(16)
```

#### `ok`

```mojo
def ok() -> Self
```

#### `err`

```mojo
def err(code: Int, message: String) -> Self
```

#### `with_details`

```mojo
def with_details(self, var details: List[UInt8]) -> Self
```

Return a copy of this status with the ``grpc-status- details-bin`` payload attached. The caller owns the bytes; the trailer emitter base64-encodes them when serialising the trailing HEADERS field set.

#### `is_ok`

```mojo
def is_ok(self) -> Bool
```

#### `name`

```mojo
def name(self) -> String
```

Return the canonical short name for the status code. Unknown numeric codes (outside 0..16) return ``"UNKNOWN_CODE_<n>"`` so logs always have something to grep for.

## Functions

### `grpc_message_encode`

```mojo
def grpc_message_encode(message: String) -> String
```

Percent-encode ``message`` for the ``grpc-message`` field.

gRPC's PROTOCOL-HTTP2 carries the message as percent-encoded UTF-8:
every byte outside ``0x20..0x7E``, and ``%`` itself, becomes
``%XX``. Sent raw, a non-ASCII message reached clients as mojibake
and a CR or LF in it was a field-injection vector on any transport
that did not reject it.

### `grpc_message_decode`

```mojo
def grpc_message_decode(value: String) -> String
```

Undo :func:`grpc_message_encode` on a received ``grpc-message``.

The spec asks a receiver not to fail on a malformed value, so a
``%`` not followed by two hex digits is kept as it is, and bytes
that do not decode to valid UTF-8 are replaced, not raised on.

## Aliases

### `GRPC_STATUS_OK`

```mojo
comptime GRPC_STATUS_OK = GrpcStatus.OK
```

### `GRPC_STATUS_CANCELLED`

```mojo
comptime GRPC_STATUS_CANCELLED = GrpcStatus.CANCELLED
```

### `GRPC_STATUS_UNKNOWN`

```mojo
comptime GRPC_STATUS_UNKNOWN = GrpcStatus.UNKNOWN
```

### `GRPC_STATUS_INVALID_ARGUMENT`

```mojo
comptime GRPC_STATUS_INVALID_ARGUMENT = GrpcStatus.INVALID_ARGUMENT
```

### `GRPC_STATUS_DEADLINE_EXCEEDED`

```mojo
comptime GRPC_STATUS_DEADLINE_EXCEEDED = GrpcStatus.DEADLINE_EXCEEDED
```

### `GRPC_STATUS_NOT_FOUND`

```mojo
comptime GRPC_STATUS_NOT_FOUND = GrpcStatus.NOT_FOUND
```

### `GRPC_STATUS_ALREADY_EXISTS`

```mojo
comptime GRPC_STATUS_ALREADY_EXISTS = GrpcStatus.ALREADY_EXISTS
```

### `GRPC_STATUS_PERMISSION_DENIED`

```mojo
comptime GRPC_STATUS_PERMISSION_DENIED = GrpcStatus.PERMISSION_DENIED
```

### `GRPC_STATUS_RESOURCE_EXHAUSTED`

```mojo
comptime GRPC_STATUS_RESOURCE_EXHAUSTED = GrpcStatus.RESOURCE_EXHAUSTED
```

### `GRPC_STATUS_FAILED_PRECONDITION`

```mojo
comptime GRPC_STATUS_FAILED_PRECONDITION = GrpcStatus.FAILED_PRECONDITION
```

### `GRPC_STATUS_ABORTED`

```mojo
comptime GRPC_STATUS_ABORTED = GrpcStatus.ABORTED
```

### `GRPC_STATUS_OUT_OF_RANGE`

```mojo
comptime GRPC_STATUS_OUT_OF_RANGE = GrpcStatus.OUT_OF_RANGE
```

### `GRPC_STATUS_UNIMPLEMENTED`

```mojo
comptime GRPC_STATUS_UNIMPLEMENTED = GrpcStatus.UNIMPLEMENTED
```

### `GRPC_STATUS_INTERNAL`

```mojo
comptime GRPC_STATUS_INTERNAL = GrpcStatus.INTERNAL
```

### `GRPC_STATUS_UNAVAILABLE`

```mojo
comptime GRPC_STATUS_UNAVAILABLE = GrpcStatus.UNAVAILABLE
```

### `GRPC_STATUS_DATA_LOSS`

```mojo
comptime GRPC_STATUS_DATA_LOSS = GrpcStatus.DATA_LOSS
```

### `GRPC_STATUS_UNAUTHENTICATED`

```mojo
comptime GRPC_STATUS_UNAUTHENTICATED = GrpcStatus.UNAUTHENTICATED
```
