rustwright-core 0.1.1

Rust CDP core for a Python Playwright-compatible automation API
# Rustwright C# alpha binding

This package is a synchronous .NET 8 P/Invoke binding for the Rustwright C ABI. It contains:

- `Rustwright/`: the public Chromium, Browser, and Page API plus all 19 native declarations.
- `Smoke/`: the reference inline-HTML smoke executable.
- `Runner/`: the manifest-v1 benchmark runner and strict manifest validation.

Run these commands from the repository root. When `--lib` is omitted, the binding looks for the platform-specific shared library in `target/release/` (`librustwright_capi.dylib` on macOS or `librustwright_capi.so` on Linux).

## Install (NuGet)

The package is not published yet. Once available from NuGet, install it with:

```sh
dotnet add package Rustwright
```

The package carries native libraries for macOS (Arm64 and x64), Linux (Arm64 and x64), and Windows x64. Package consumers do not need to configure a native library path explicitly.

## Build from source

Build the C ABI before running either source project:

```sh
cargo build -p rustwright-capi --release --locked
```

## Smoke

```sh
dotnet run --project csharp/Smoke -- --lib target/release/librustwright_capi.dylib
```

## Benchmark runner

```sh
dotnet run --project csharp/Runner -- --manifest bindings/cases/smoke.json --lib target/release/librustwright_capi.dylib --out /tmp/csharp-layout.json
```

The runner also accepts `--cases id1,id2`, preserves manifest order, and exits 0 only when all selected cases pass. `--manifest`, `--lib`, and `--out` are required.

## API sketch

```csharp
NativeLibraryLoader.Configure("target/release/librustwright_capi.dylib");
using var browser = Chromium.Launch(new LaunchOptions { Headless = true });
using var page = browser.NewPage();
page.Goto("data:text/html,hello");
Console.WriteLine(page.Title());
```

`LaunchOptions` properties serialize to the core snake_case wire names. `ScreenshotOptions` properties serialize to the Node-compatible `fullPage` and `omitBackground` names. An omitted native timeout is always sent as `double.NaN`.

The evaluate decoder recursively unwraps Rustwright array/object/reference tags. It maps JavaScript dates to `DateTimeOffset`, URLs to `Uri`, bigint values to `BigInteger`, regular expressions and errors to binding records, and non-finite numbers to their .NET `double` equivalents. JavaScript `undefined`, symbols, and functions have no direct JSON/.NET representation and fall back to `null`.

Opaque handles are owned by `SafeHandle` instances. Explicit `Close` performs browser/page lifecycle shutdown before the Rust allocation is freed; `Dispose` is idempotent. Rust-owned strings and screenshot buffers are copied into managed memory and released through the matching ABI deallocator.