From 3b9c1496664318a3ba0ff2f0e42df4b1fbf9b343 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Tue, 27 Oct 2026 19:35:48 -0700 Subject: [PATCH 1/2] chore(quest): claim quest/m1/ffi-export/paths.md Quest-Claim: 93b76c88e45c0fcd From 5e8ba1c0e9d5236aa3cdc7bb437e86302551a559 Mon Sep 17 00:00:00 2001 From: Luke Curley <432854+kixelated@users.noreply.github.com> Date: Tue, 27 Oct 2026 20:04:09 -0700 Subject: [PATCH 2/2] feat(ffi): export moq's owned Path Bump the moq pin to moq-dev/moq@c764ace, past moq-dev/moq#6843, which drops Path's and Relative's lifetimes. Path::new, strip_prefix, and Relative::new now export, AsPath and the borrow methods are gone, and only Path::from_static's 'static borrow is refused. moq.c builds, joins, strips, and resolves paths from C. The exclude list follows the rest of the bump: moq-tokio's tokens moved to moq-net's auth module, track::Querying became Resolving, and StatsUnavailable and Connection::authenticated are gone. Co-Authored-By: Claude Opus 5.5 --- ffi/moq/ffi.toml | 21 +++++++++------------ ffi/moq/moq.c | 26 +++++++++++++++++++++++--- quest/m1/ffi-export/README.md | 1 - quest/m1/ffi-export/paths.md | 14 -------------- ts/justfile | 2 +- 5 files changed, 33 insertions(+), 31 deletions(-) delete mode 100644 quest/m1/ffi-export/paths.md diff --git a/ffi/moq/ffi.toml b/ffi/moq/ffi.toml index 2d762effd..899acea4f 100644 --- a/ffi/moq/ffi.toml +++ b/ffi/moq/ffi.toml @@ -8,7 +8,6 @@ prefix = "moq" # a hand-written wrapper still has to cover. exclude = [ "ALPNS", - "AsPath", "BoundsExceeded", "Client::connect", "Client::with_url", @@ -20,10 +19,8 @@ exclude = [ "Hops::iter", "IntoBytes", "InvalidEpoch", - "Path::borrow", - "Path::new", + "Path::from_static", "Path::parts", - "Path::strip_prefix", "Server::accept", "Server::accept_request", "Timed", @@ -35,6 +32,13 @@ exclude = [ "Versions::iter", "announce::Announce", "announce::Consumer::poll_synced", + "auth::Dial", + "auth::EmptyToken", + "auth::Token", + "auth::Tokens::changed", + "auth::Tokens::dial", + "auth::Tokens::new", + "auth::Tokens::set", "bytes", "cache::Pool::poll", "frame::Buffer", @@ -47,8 +51,6 @@ exclude = [ "origin::Driver::poll", "origin::Requesting", "origin::Routing", - "path::Relative::borrow", - "path::Relative::new", "server::Handshake", "stats::Failure::ALL", "stats::RefusalKind::ALL", @@ -62,14 +64,13 @@ exclude = [ "time::Driver", "time::run", "track::Fetching", - "track::Querying", + "track::Resolving", "track::Subscribing", "track::Subscription::ranges", "track::Subscription::with_ranges", "transport::Error", "transport::MaybeSend", "transport::MaybeSync", - "transport::StatsUnavailable", "transport::memory::Chunks", "transport::memory::SendStream", "transport::poll::AcceptBi", @@ -175,10 +176,7 @@ exclude = [ "connect::Config::tokens", "connect::Config::url", "connect::Config::version", - "connect::EmptyToken", "connect::Resolved::bind", - "connect::Token", - "connect::Tokens::set", "connection::Monitor::poll_presence", "crypto::install_default", "crypto::provider", @@ -208,7 +206,6 @@ exclude = [ "quic::driver::Connecting", "quic::driver::Connection::accept_bi", "quic::driver::Connection::accept_uni", - "quic::driver::Connection::authenticated", "quic::driver::Connection::close", "quic::driver::Connection::close_reason", "quic::driver::Connection::closed", diff --git a/ffi/moq/moq.c b/ffi/moq/moq.c index 3d3da4b5a..d6bd73794 100644 --- a/ffi/moq/moq.c +++ b/ffi/moq/moq.c @@ -153,7 +153,8 @@ int main(void) { root = moq_origin_producer_root(scoped); CHECK(is(moq_path_as_str(root), "room")); moq_path_free(root); - moq_path *absolute = moq_origin_producer_absolute(scoped, str("alice")); + moq_path *absolute = NULL; + CHECK(moq_origin_producer_absolute(scoped, str("alice"), &absolute, &err)); CHECK(is(moq_path_as_str(absolute), "room/alice")); moq_path_free(absolute); moq_patterns *allowed = moq_origin_producer_allowed(scoped); @@ -161,7 +162,7 @@ int main(void) { CHECK(!moq_patterns_matches(allowed, str("bob"))); moq_patterns_free(allowed); moq_origin_consumer *reader = moq_origin_producer_consume(scoped); - absolute = moq_origin_consumer_absolute(reader, str("bob")); + CHECK(moq_origin_consumer_absolute(reader, str("bob"), &absolute, &err)); CHECK(is(moq_path_as_str(absolute), "room/bob")); moq_path_free(absolute); moq_origin_consumer_free(reader); @@ -175,9 +176,28 @@ int main(void) { moq_broadcast_info *stamped = moq_broadcast_producer_info(created); moq_path *path = moq_broadcast_info_path(stamped); CHECK(is(moq_path_as_str(path), "room/alice")); - moq_path *joined = moq_path_join(path, str("cam")); + + /* Paths own their segments, so C builds them, and relative ones, from a string. */ + moq_path *cam = NULL; + moq_path_too_long *too_long = NULL; + CHECK(moq_path_new(str("/cam/"), &cam, &too_long)); + CHECK(is(moq_path_as_str(cam), "cam")); + moq_path *joined = NULL; + CHECK(moq_path_join(path, cam, &joined, &too_long)); CHECK(is(moq_path_as_str(joined), "room/alice/cam")); + moq_path *stripped = moq_path_strip_prefix(joined, path); + CHECK(stripped != NULL && moq_path_eq(stripped, cam)); + moq_path_free(stripped); + CHECK(moq_path_strip_prefix(path, joined) == NULL); + moq_relative *up = NULL; + CHECK(moq_relative_new(str("../bob"), &up, &too_long)); + moq_path *resolved = NULL; + CHECK(moq_path_resolve(joined, up, &resolved, &too_long)); + CHECK(is(moq_path_as_str(resolved), "room/bob")); + moq_path_free(resolved); + moq_relative_free(up); moq_path_free(joined); + moq_path_free(cam); moq_path_free(path); moq_broadcast_info_free(stamped); moq_broadcast_producer_free(created); diff --git a/quest/m1/ffi-export/README.md b/quest/m1/ffi-export/README.md index d728049b2..86c5af0ed 100644 --- a/quest/m1/ffi-export/README.md +++ b/quest/m1/ffi-export/README.md @@ -35,7 +35,6 @@ Every generator on the C ABI: ## Required -- [Paths without a lifetime](/quest/m1/ffi-export/paths.md) - moq's owned `Path` exports, and its excludes go - [Instances the config can't name yet](/quest/m1/ffi-export/instance-keys.md) - `&T` keys, `IntoIterator` as a `Vec`, `serde_json::Value`, and `Catalog<()>` - [Closures lent for the call](/quest/m1/ffi-export/lent-closures.md) - a callback borrowed for one call, as `modify`'s `Guard` needs - [One library from several crates](/quest/m1/ffi-export/crates.md) - the C names the several-crate export still can't give diff --git a/quest/m1/ffi-export/paths.md b/quest/m1/ffi-export/paths.md deleted file mode 100644 index b7fbd8153..000000000 --- a/quest/m1/ffi-export/paths.md +++ /dev/null @@ -1,14 +0,0 @@ -# [S] Paths without a lifetime - -## Goal - -The exporter exports moq's owned `Path`: the census exports `Path::new`, `strip_prefix`, -and `Relative::new`, [the exclude list](/ffi/moq/ffi.toml) drops `AsPath` and the `borrow` -methods, and only `Path::from_static`'s `'static` borrow is refused. - -## Plan - -[moq-dev/moq#6843](https://github.com/moq-dev/moq/pull/6843), which makes `Path` owned, -merged on 2026-10-27. Bump the moq pin past it and report the census before and after. - -Public API: the C names moq's bindings get. diff --git a/ts/justfile b/ts/justfile index c678a7b24..b0a714a30 100644 --- a/ts/justfile +++ b/ts/justfile @@ -9,7 +9,7 @@ set shell := ["bash", "-euo", "pipefail", "-c"] export PATH := if env("RUST2_TS_TOOLCHAIN", "") == "" { env("PATH") } else { env("RUST2_TS_TOOLCHAIN") / "bin:" + env("PATH") } # The moq revision `moq` translates by default. -moq_rev := "88448d9c66ddf4b202eb873edbfe0ef859835a21" +moq_rev := "c764acebb90b5c102a8ea90207dd125ae4fd326b" default: @just --list