Skip to content

niso-base

Generated from crates/niso-base/CONTRACT.md when the site was built at 7aa23e2.

The vocabulary every niso crate shares: object handles (Obj), the error type every API returns (ErrorCode, Error, Result), and the C value types the generated shims read arguments through and write results into. It owns no state, runs nothing and has no dependencies, so any crate can depend on it, and a change to it rebuilds everything: it changes rarely and deliberately.

It does not own interface ids (InterfaceId stays the generated enum in niso-core until niso-compose hashes names, migration step 6), the conversion from storage’s DriverError (niso-core until step 5), or the IDL callback structs (function pointer, userdata, destructor), which niso-idl generates per callback signature into the crate that owns the IDL.

  • Rust:
    • Obj (a u64 handle, #[repr(transparent)]) and OBJECT_BIT.
    • ErrorCode (#[repr(i32)]), Error { code, message }, Result<T>, err(code, message).
    • c: NisoStr, NisoBytes, NisoHandles, NisoStrs, NisoHeld and Held, DropFn, BufferOrString, BytesOrStr, SharedBytesOrStr, NodeOrString, PairsOrString, and the readers str_in, opt_str_in, strs_in, bytes_in, bytes_mut_in, opt_bytes_in, slice_in, buffer_or_string_in, obj_in, opt_obj_in, dict_in.
    • testing (below) and, behind the contract-tests feature, contract.
  • C (include/status.h and include/types.h, sections of the composed niso_runtime.h): enum niso_status holds ErrorCode‘s values; niso_str, niso_bytes, niso_handles, niso_strs, niso_node_or_string, niso_buffer_or_string, niso_held and niso_drop_fn are the c types’ layouts.
  • IDL: none.
  • Glue: none. The glue core’s code-to-name table (makeError, bindings/js/glue/exceptions.js) mirrors ErrorCode.

niso-core re-exports all of it under the old paths (niso_core::Obj, niso_core::ErrorCode, niso_core::ffi::NisoStr, …).

None.

No niso dependencies and no third-party ones.

  1. ErrorCode’s numeric values are ABI: each equals its NISO_* constant in include/status.h, every constant but NISO_OK = 0 is an ErrorCode, and the values are distinct and non-zero. contract::error_codes, run on include/status.h, the section of the header the C API ships that is the one source of the numbers.
  2. A handle is one u64. Object handles set OBJECT_BIT (the top bit); handles without it are nodes, whose meaning only the document knows. 0 is no object: obj_in(0) is a TypeError and opt_obj_in(0) is None. contract::handles.
  3. The C value structs are a pointer and a length (plus is_string for BufferOrString, a handle for NodeOrString), in C layout. contract::layouts.
  4. Readers never dereference null: a null pointer reads as empty (bytes, slices), "" for a zero-length string, None for the opt_ forms, and a TypeError where a value is required; text that is not UTF-8 is a TypeError. contract::conversions.
  5. A NisoHeld with null data is no value; a taken Held calls the binding’s drop exactly once, when it is dropped. contract::held.

Everything here is plain data. The c structs hold raw pointers and are not Send; their validity is the caller’s, as the unsafe readers document.

No allocation except strs_in (a Vec of borrowed &str) and Error’s message. Its code in niso-app is a few hundred bytes.

testing::DropProbe makes NisoHeld values whose destructor bumps a counter, for tests that a value is dropped exactly once. testing::c_str borrows a Rust string as a C value. Nothing else here needs faking.

Shared types only. cargo test -p niso-base runs the contract suite.