# Design

> UCall for Mojo

- __A thin layer over the C ABI.__
  Every name follows `c/ucall/`, and enums mirror C enums, never strings.
  Every one of the 55 exported functions is bound, and so are both callback types, the log sink and the peer authorizer; typed JSON handlers stay Python's, and Mojo handlers read and write bytes.
- __Handlers are compile-time parameters.__
  One `thin abi("C")` trampoline is instantiated per handler, and the context the library passes back addresses the `Server`, which is not `Movable` for that reason.
- __Pointers keep their types and their borrows.__
  A C pointer that may be null is an `Optional[Pointer]`, a view carries the origin of what it borrows, and only opaque handles and `void *` state cross as an integer `Address`.

`from ucall import Library`

## Library

A reference to the loaded library, cheap to copy and shared by everything it creates.

```mojo
struct Library
```

Every handle carries one, which is what keeps the shared object mapped for as long as anything
can still call into it.

- `shared` `ArcPointer[_Loaded]`: The handle and its symbols, refcounted so the last holder unmaps the object.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`

## __init__

Opens the shared object and resolves it, which every handle then shares.

```mojo
def __init__(out self)
```

Raises: With [`LIBRARY_MISSING`](https://www.unum.cloud/docs/ucall/mojo/errors.md#LIBRARY_MISSING), when nothing is on the loader path, with [`VERSION_MISMATCH`](https://www.unum.cloud/docs/ucall/mojo/errors.md#VERSION_MISMATCH) when what loaded is another major version, or with [`SYMBOL_MISSING`](https://www.unum.cloud/docs/ucall/mojo/errors.md#SYMBOL_MISSING) when it does not export an entry point the binding needs.

## symbols

The resolved entry points, borrowed rather than copied on every call.

```mojo
def symbols(self) -> ref[self.shared.symbols] Symbols
```

## version

The linked library's major, minor and patch. Calls `ucall_version`.

```mojo
def version(self) -> Tuple[Int, Int, Int]
```

## version_name

The linked library's version, including a release-candidate suffix. Calls `ucall_version_name`.

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

## status_name

The library's spelling of a status, as [`OUT_OF_MEMORY`](https://www.unum.cloud/docs/ucall/mojo/errors.md#OUT_OF_MEMORY) spells "out-of-memory". Calls `ucall_status_name`.

```mojo
def status_name(self, status: Status) -> String
```

## status_from_name

Reads a spelling back; [`INVALID_ARGUMENT`](https://www.unum.cloud/docs/ucall/mojo/errors.md#INVALID_ARGUMENT) when unrecognized. Calls `ucall_status_from_name`.

```mojo
def status_from_name(self, name: StringSpan) -> Status
```

## io_backend_name

The library's spelling of an I/O backend, as [`LINUX_URING618`](https://www.unum.cloud/docs/ucall/mojo/serving.md#LINUX_URING618) spells "linux-uring618". Calls `ucall_io_backend_name`.

```mojo
def io_backend_name(self, backend: Backend) -> String
```

## io_backend_from_name

Reads a spelling back; [`AUTOMATIC`](https://www.unum.cloud/docs/ucall/mojo/serving.md#AUTOMATIC) when unrecognized. Calls `ucall_io_backend_from_name`.

```mojo
def io_backend_from_name(self, name: StringSpan) -> Backend
```

## cpu_class_name

The library's spelling of a CPU class, as [`AWS_G5`](https://www.unum.cloud/docs/ucall/mojo/threads-and-polling.md#AWS_G5) spells "aws-g5". Calls `ucall_cpu_class_name`.

```mojo
def cpu_class_name(self, cpu_class: CPUClass) -> String
```

## cpu_class_from_name

Reads a spelling back; [`UNKNOWN`](https://www.unum.cloud/docs/ucall/mojo/threads-and-polling.md#UNKNOWN) when unrecognized. Calls `ucall_cpu_class_from_name`.

```mojo
def cpu_class_from_name(self, name: StringSpan) -> CPUClass
```

## decode_percent

Decodes the `%XX` escapes of `encoded`, like a query value, and '+' as a space in [`QUERY`](https://www.unum.cloud/docs/ucall/mojo/requests.md#QUERY) mode. Calls `ucall_decode_percent`.

```mojo
def decode_percent(self, encoded: Span[UInt8], mode: PercentMode) -> List[UInt8]
```

- `encoded`: A path or a query value, still percent-encoded.
- `mode`: Whether a '+' is itself or a space.

Raises: [`Error`](https://www.unum.cloud/docs/ucall/mojo/errors.md#Error) with [`INVALID_ARGUMENT`](https://www.unum.cloud/docs/ucall/mojo/errors.md#INVALID_ARGUMENT) on a '%' without two hexadecimal digits.

## generate_noise_keypair

Draws a fresh static keypair from the operating system's entropy. Calls `ucall_noise_key_generate`.

```mojo
def generate_noise_keypair(self) -> Tuple[SIMD[.uint8, 32], SIMD[.uint8, 32]]
```

Raises: [`Error`](https://www.unum.cloud/docs/ucall/mojo/errors.md#Error) if the operating system offers no entropy.

## derive_noise_public_key

The public key of a stored private key, as peers see it during the handshake. Calls `ucall_noise_key_derive`.

```mojo
def derive_noise_public_key(self, private_key: SIMD[.uint8, 32]) -> NoiseKey
```

- `private_key`: The secret scalar.

Raises: [`Error`](https://www.unum.cloud/docs/ucall/mojo/errors.md#Error) if the library refuses the key.

