Add minimal ActivityPub vocab types#13
Conversation
📝 WalkthroughWalkthroughThis PR establishes a minimal ActivityPub vocabulary crate for Feder by introducing shared workspace dependencies ( ChangesMinimal ActivityPub Vocabulary Implementation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/feder-vocab/src/lib.rs`:
- Around line 77-83: The Actor struct is currently constrained to Person via the
PersonType discriminator (pub kind: PersonType), which rejects non-person
ActivityPub actors; change this public API by introducing a broader ActorType
enum (e.g., ActorType with variants Person, Service, Group, Application, etc.)
and replace PersonType with ActorType in the Actor struct, updating serde
attributes as needed to preserve the "type" field; then update all usages
referenced by symbol names (Follow.actor, Follow.object, Accept.actor,
Create.actor, Note.attributedTo) to accept ActorType instead of PersonType (or
alternatively rename the struct to Person if you intend to keep Person-only
semantics across those symbols). Ensure serialization/deserialization continues
to map the "type" field correctly and add tests for non-Person actor types.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 25a1d38f-662f-4d93-b45e-98f64eb449d2
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (4)
Cargo.tomlcrates/feder-vocab/Cargo.tomlcrates/feder-vocab/src/lib.rscrates/feder-vocab/tests/phase1_shapes.rs
| /// A minimal ActivityPub actor for Phase 1 core tests. | ||
| #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] | ||
| pub struct Actor { | ||
| #[serde(rename = "@context", skip_serializing_if = "Option::is_none")] | ||
| pub context: Option<Iri>, | ||
| #[serde(rename = "type")] | ||
| pub kind: PersonType, |
There was a problem hiding this comment.
Actor is currently hard-coded to Person.
Line 83 makes the public Actor model reject any valid ActivityPub actor whose "type" is not "Person". That breaks non-person actors end-to-end in Follow.actor, Follow.object, Accept.actor, Create.actor, and Note.attributedTo, even though the API is named generically as Actor. Either rename this model to Person or widen the discriminator to an ActorType enum before locking in the public API.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/feder-vocab/src/lib.rs` around lines 77 - 83, The Actor struct is
currently constrained to Person via the PersonType discriminator (pub kind:
PersonType), which rejects non-person ActivityPub actors; change this public API
by introducing a broader ActorType enum (e.g., ActorType with variants Person,
Service, Group, Application, etc.) and replace PersonType with ActorType in the
Actor struct, updating serde attributes as needed to preserve the "type" field;
then update all usages referenced by symbol names (Follow.actor, Follow.object,
Accept.actor, Create.actor, Note.attributedTo) to accept ActorType instead of
PersonType (or alternatively rename the struct to Person if you intend to keep
Person-only semantics across those symbols). Ensure
serialization/deserialization continues to map the "type" field correctly and
add tests for non-Person actor types.
| pub const ACTIVITYSTREAMS_CONTEXT: &str = "https://www.w3.org/ns/activitystreams"; | ||
|
|
||
| /// An absolute ActivityPub/ActivityStreams identifier. | ||
| pub type Iri = String; |
There was a problem hiding this comment.
Instead of aliasing type Iri = String, how about introducing RiStr from the iri-string crate?
Summary
Actor,Note,Follow,Accept, andCreate<T>typemarker enums such asFollowType,AcceptType, andCreateTypeReference<T>for ID-or-embedded-object protocol fieldsOneOrMany<T>for scalar-or-array protocol fieldsCloses #5.
Design Notes
This keeps
crates/feder-vocabscoped to protocol data only. It does not add core behavior, runtime I/O, fetching, storage, delivery, or full JSON-LD expansion.Reference<T>exists because ActivityPub object slots can appear as either an IRI string or an embedded object. For example,actor,object, andattributedTomay be represented as:or:
So
Reference<Actor>means "this protocol field contains either an actor IRI or an embedded actor object." It does not fetch, cache, dereference, or resolve the actor.OneOrMany<T>exists because ActivityStreams fields are often represented as a single value or an array depending on cardinality. Absence is still modeled byOption<OneOrMany<T>>on future containing types.The singleton
*Typeenums follow the same broad serde pattern used byactivitypub-federation: concrete structs carry a fixed#[serde(rename = "type")] kindfield, so deserializing a JSON object with the wrong ActivityStreams type fails early. Flexible shape selection is handled with#[serde(untagged)]only where the protocol genuinely allows multiple JSON shapes.JSON-LD Scope
This crate intentionally models a compact ActivityStreams profile rather than full JSON-LD processing.
The Phase 1 vocab types use ordinary serde over common ActivityPub field names such as
id,type,actor,object,attributedTo, andcontent. Helpers likeReference<T>andOneOrMany<T>cover common fediverse JSON shape variants without requiring JSON-LD expansion, compaction, RDF conversion, or remote context loading.This is intended to keep the portable core usable by constrained runtimes. A future Linux runtime may add optional full JSON-LD normalization, but
feder-coreshould not depend on it.Validation
cargo fmt --checkcargo testmise run checkSummary by CodeRabbit
New Features
Tests
Chores