Docs contents

Library and Rust integration design

Common operations will use typed Nagi APIs backed by existing Rust libraries. Advanced operations and custom foundations will use Rust integration. This serves both developers writing applications without knowing Rust and developers combining Rust libraries.

This page includes unimplemented proposals. For current usage, see imports and Rust, nagi.toml, and the sample projects.

On this page

Available features and missing pieces

Area Available today Unsupported or undecided
Imports Relative files, as, multiple-name from, registered standard modules Package management and visibility declarations
Standard APIs std.http.server, std.actor Separate JSON and database modules
Standard resources App, Request, Response, Actor, Supervisor, and related types User-defined resource registration
Rust integration Sync/async extern functions, typed arguments/results, handwritten adapters Direct use of arbitrary Rust types/traits and a stable external ABI
Cargo dependencies Version, path, features, default-features, package Generation that excludes unused runtime dependencies
Database SQLite, fixed bind shapes, conversion of rows into classes PostgreSQL, general parameters, pools, and transaction APIs

check checks extern declarations and Nagi calls. build checks them against Rust implementations and crates. Extern functions cannot return views.

Shared logic and adapters

Put types, validation, and calculations in Nagi modules and use them from CLI, HTTP, or other entry points. Rust adapters convert external types into Nagi-supported types. An independent Rust crate uses its own types; the adapter converts them to generated application classes.

The HTTP authentication example uses standard APIs for headers and business errors. custom-http calls synchronous Nagi callbacks from a Rust Axum server. Its Rust code owns capacities, deadlines, and shutdown; standard HTTP settings do not apply automatically.

Modules and name resolution

Aliases of the same module refer to the same definitions; same-named classes in different modules are distinct types. Type checks, High/Low, Rust generation, and editors use these identities. Imported names are not automatically re-exported.

Types and operations in std.http.server and std.actor are registered by the compiler. Standard module names do not resolve to local lookalike files. Adding an ordinary library should not require adding language keywords.

Cargo dependency settings

See nagi.toml for supported settings. Paths resolve relative to the manifest, so changing the generated directory preserves the referenced crate. check, lower, and symbols do not invoke Cargo.

Cargo combines features across dependency paths. Rebuilding preserves the generated Cargo.lock, but it does not pin path dependency source contents. nagic build --locked is unsupported.

Selecting runtime features

Unimplemented proposal. Separate HTTP, JSON, SQLite, and other dependencies according to application needs. Standard HTTP applications without a database currently still include the runtime's SQLite dependency.

Serde and row conversions, exported types, and error conversion generation also need conditional support. While all functions are emitted, dependencies cannot be removed by inspecting only direct calls from the entry point. Existing Rust adapter compatibility also needs checking.

Opaque types and asynchronous work

Proposed contracts for additional resource types. Current classes represent data; they do not substitute for native clients or connections.

Contract Questions to resolve
Identity Map Nagi types to Rust types; distinguish same-named types from different providers
Ownership and sharing Move by default; explicitly permit borrowing, cloning, and sharing by type
Borrowing Keep owners alive across await; distinguish read-only views from exclusive operations
Threads rustc validates native Send/Sync and traits; do not grant them universally
Cleanup Define explicit async close and who owns work that remains after drop

Drop cannot await. Dropping a future stops the caller waiting without necessarily canceling accepted database work or external sends. Evaluate general traits and new variadic syntax only after establishing whether this boundary requires them.

Requirements for a general database API

Separate drivers with common conventions; new APIs are unimplemented. SQLite and PostgreSQL will use separate modules and resource types, preserving SQL dialect, type, and transaction differences. Module names remain undecided.

Area Contract to define first
Parameters Arbitrary typed values, typed NULLs, and ownership for str, bytes, and views
Rows Field names, column order, NULLs, integer ranges, and decoding errors
Operations and errors execute/one/all shapes, absence, connection/wait/SQL/decoding failures
Transactions Hold one connection; consume the caller's handle on commit/rollback; assign cleanup ownership after cancellation
Pools Closure state shared by clones, stopping new acquisitions, and waiting for operations and cleanup

Serializing transaction operations inside a library differs from rejecting concurrent use in Nagi's check. The latter requires additional checking over future lifetimes. The extent of static guarantees remains undecided.

An unconfirmed commit outcome does not imply rollback or safe retry. Evaluate driver-side distinctions between unsent work, explicit database rejection, and response loss after sending.

Do not translate SQL automatically or send BEGIN/COMMIT through different pooled connections. Static SQL/schema checks and runtime checks of actual types/NULLs are separate. Ordinary check does not validate SQL. Nagi 0.1.10 supports explicit SQLite checks, which do not guarantee actual value types or NULL behavior.

Comparing HTTP foundations

Evaluate Axum/Tower first against the current standard HTTP implementation. Adoption is undecided and the comparison has not been run. Axum also uses Hyper: compare routing and middleware within the same connection management, then evaluate listener and shutdown changes separately.

Match public APIs, admission capacity, body/header limits, deadlines, panic responses, and shutdown. Evaluate throughput, latency, CPU, memory, overload recovery, and maintenance costs. Existing measurements are not results of this adoption comparison.

The 0.2.0 outgoing HTTP client uses fixed operations and finite budgets registered by a trusted Rust host. Its contract distinguishes response status, transport failures, receive limits, deadlines, and actual termination/join. There is no general client API accepting arbitrary URLs or raw header maps.

Implementation order

Address existing type/ownership consistency, native resource contracts, SQLite validation, and PostgreSQL support in that order. Treat HTTP foundation comparison as a separate evaluation and check public API compatibility.

Preserve existing imports, built-ins, Rust integration, and Low compatibility. Check existing examples and editors. Measure dependency reductions through Cargo features, build times, and output size.

References: Cargo dependencies, features, Send/Sync, Drop, Axum, Tower.

Nagi 0.2.0 · DocsPage source