Something went wrong. Try again.
zig library for building requests to query inference providers usage limits
Something went wrong. Try again.
3.5 kB · 118 lines
Zig
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119//! C ABI over the pure core.//!//! One rule for every export: return a JSON string the caller frees with `usage_free`,//! and report failure *inside* that JSON. A host never has to tell "no error" apart from//! "no data", and NULL means only that allocation failed.//!//! The core owns no cross-call state; the host owns it via usage_state and passes it back.const std = @import("std");const usage = @import("usage.zig");
const alloc = std.heap.c_allocator;
/// Opaque cross-round state struct owned by the host.pub const usage_state = struct { inner: usage.State,};
/// C callers (Swift included) pass NULL for an absent string; treat it as empty rather/// than dereferencing a null pointer.fn slice(ptr: ?[*]const u8, len: usize) []const u8 { const p = ptr orelse return ""; return p[0..len];}
fn finish(w: *usage.Writer) ?[*:0]u8 { return alloc.dupeZ(u8, w.items()) catch null;}
fn errorResult(a: std.mem.Allocator, text: []const u8) ?[*:0]u8 { var w = usage.Writer.init(a); w.raw("{\"error\":") catch return null; w.string(text) catch return null; w.raw("}") catch return null; return finish(&w);}
fn message(error_code: anyerror) []const u8 { return switch (error_code) { error.OutOfMemory => "out of memory", else => "usage query failed", };}
export fn usage_abi_version() u32 { return usage.abi_version;}
export fn usage_free(ptr: ?[*:0]u8) void { if (ptr) |p| alloc.free(std.mem.span(p));}
export fn usage_state_new() ?*usage_state { const s = alloc.create(usage_state) catch return null; s.inner = usage.State.init(alloc); return s;}
export fn usage_state_free(state: ?*usage_state) void { if (state) |s| { s.inner.deinit(); alloc.destroy(s); }}
export fn usage_providers() ?[*:0]u8 { var arena = std.heap.ArenaAllocator.init(alloc); defer arena.deinit(); const a = arena.allocator();
var w = usage.Writer.init(a); usage.writeProviders(&w) catch return null; return finish(&w);}
export fn usage_advance( state: ?*usage_state, provider: ?[*]const u8, provider_len: usize, credential_json: ?[*]const u8, credential_len: usize, responses_json: ?[*]const u8, responses_len: usize, now_ms: i64,) ?[*:0]u8 { var arena = std.heap.ArenaAllocator.init(alloc); defer arena.deinit(); const a = arena.allocator();
const prov_slice = slice(provider, provider_len); const cred_slice = slice(credential_json, credential_len); const resp_slice = slice(responses_json, responses_len); const state_ptr: ?*usage.State = if (state) |s| &s.inner else null;
const outcome = usage.advance(a, state_ptr, prov_slice, cred_slice, resp_slice, now_ms) catch |e| { return errorResult(a, message(e)); };
var w = usage.Writer.init(a); usage.writeStep(&w, outcome) catch |e| { return errorResult(a, message(e)); }; return finish(&w);}
export fn usage_credentials_from_access_token(jwt: ?[*]const u8, jwt_len: usize) ?[*:0]u8 { var arena = std.heap.ArenaAllocator.init(alloc); defer arena.deinit(); const a = arena.allocator();
var w = usage.Writer.init(a); const outcome = usage.claimsFromAccessToken(a, slice(jwt, jwt_len), &w) catch |e| { return errorResult(a, message(e)); }; switch (outcome) { .ok => return finish(&w), .err => |text| return errorResult(a, text), }}