pub trait WritableRecord: Serialize + Sealed { }Expand description
What a record-write primitive will accept.
The bound that makes vetting unskippable. The write primitives were
generic over T: Serialize, and lexicon::Subscription derives
Serialize — so create_record(nsid::SUBSCRIPTION, &raw_subscription)
compiled and wrote an unvetted record. On oauth::xrpc::Repo those
primitives are pub (an example drives them), so that was reachable from
any handler in this crate.
The obvious fix — dropping Serialize from Subscription — is the one
repo.rs recorded as blocked: VettedSubscription is
#[serde(transparent)] over it, so removing the derive forces a
hand-written impl, and a record-shape slip there would silently migrate
every reader’s repo. A marker trait gets the same guarantee and cannot
drift, because the wire format keeps coming from one derive.
Sealed: implementing it requires sealed::Sealed, which is private to
this module, so the list below is the whole list — nothing elsewhere in the
crate can add itself. Subscription and Saved are deliberately absent;
their vetted wrappers are here instead.
A vetted record is accepted:
use feather_reader::lexicon::Subscription;
use feather_reader::vetted::{VettedSubscription, WritableRecord};
fn writes<T: WritableRecord>(_record: &T) {}
let sub = Subscription::new("https://example.com/feed.xml", "2026-01-01T00:00:00.000Z");
writes(&VettedSubscription::new(&sub));A raw one does not compile:
use feather_reader::lexicon::Subscription;
use feather_reader::vetted::WritableRecord;
fn writes<T: WritableRecord>(_record: &T) {}
let sub = Subscription::new("https://example.com/feed.xml", "2026-01-01T00:00:00.000Z");
writes(&sub);Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".