obby_client library

The Obby IRCv3 client engine, over its C ABI.

The engine opens no socket and reads no clock. A host feeds it bytes and time, and drains bytes, events and the next deadline back out. Every method here mirrors one on the Rust side.

Classes

AllowedCommands
The set of commands the server says we may currently use. The server pushes this on connect and again whenever it changes, such as after an OPER. A batch carries additions and removals together, so both are applied at once.
Bot
What the server knows about a bot in a channel.
BotCommand
One command a bot offers.
BotRegistry
The bots we know about, keyed by their folded nick.
Capabilities
What the server offers and what we hold.
Capability
One capability the server advertised, with the value it carried if any.
Channel
A channel we are in.
ChatMessage
One message, as the model holds it.
ChunkMeta
The chunk-correlation fields riding alongside a split sdp value.
Command
Something to do on this connection.
CommandAddReaction
CommandFetchHistory
CommandGenerateToken
CommandJoin
CommandMarkRead
CommandPart
CommandQuit
CommandRedactMessage
CommandRedeemInviteCode
CommandRemoveReaction
CommandRenameChannel
CommandSendAction
CommandSendMessage
CommandSendNotice
CommandSendRawLine
CommandSendVoiceSignal
CommandSetAway
CommandSetMetadata
CommandSetNick
CommandSetTopic
CommandSetTyping
CommandSubscribeMetadata
CommandUnwatchNicks
CommandWatchNicks
CommandWhois
Config
What a host needs to give the engine before it can connect. Every field but the nick has a default, so a host deserialising one only has to supply what it actually cares about. An empty username or realname is filled in from the nick.
Conversation
A private conversation with one other person.
Invitation
An invitation link to the network or to one channel.
LinkPreview
A preview of a link someone posted, built by the server and attached to the message. The server fetches the page; a client never does. There is no capability to negotiate, and the server refuses these tags from any sender but itself, so a peer cannot forge one.
LocalUser
Who we are on this connection.
Membership
What one member holds in one channel. Only the channel-specific part. Who they are, what account they hold and whether they are away are the same everywhere, so they live once on `Person` rather than being copied into every channel they are in and drifting apart.
MessageKey
Where a message is ordered and how it is found again. Ordering is by the server's timestamp, with a monotonic sequence number breaking ties. A tie broken by arrival order alone is what the reference client relies on, and it only holds there because of an incidental property of the sort it uses.
MessageKind
What kind of thing happened.
MessageKindCtcp
MessageKindJoin
MessageKindKick
MessageKindMode
MessageKindNick
MessageKindNotice
MessageKindPart
MessageKindPrivmsg
MessageKindQuit
MessageKindTagmsg
MessageKindTopic
MessageLog
The messages of one channel or conversation, ordered and bounded.
MessageSource
Where a message came from, as sent in the :-prefixed source. A server sends its own name; a client's message arrives as nick!user@host, though a server may send only the nick.
MessageTag
One message tag. A tag with an empty value is the same as a tag with no value, so both parse to value: None.
Model
Everything the connection knows.
ModelChange
What changed, for a host that wants to react without diffing the whole model.
ModelChangeChannelJoined
ModelChangeChannelMembersChanged
ModelChangeChannelModesChanged
ModelChangeChannelParted
ModelChangeChannelRenamed
ModelChangeChannelTopicChanged
ModelChangeMessageAdded
ModelChangeMessageReacted
ModelChangeMessageRedacted
ModelChangeMetadataChanged
ModelChangeNickChanged
ModelChangeReadMarkerMoved
ModelChangeWhoisReceived
ObbyClient
One connection.
ObbyEvent
Something the host needs to know about. Events are drained with `Client::poll_event` rather than delivered through a callback, because a callback needs a different lifetime, threading and re-entrancy contract in every language this engine is bound into.
ObbyEventAllowedCommandsChanged
ObbyEventAuthToken
ObbyEventBotsChanged
ObbyEventCapabilitiesAcknowledged
ObbyEventCommandTimedOut
ObbyEventIsupportToken
ObbyEventLinkDead
ObbyEventLoggedIn
ObbyEventModelChanged
ObbyEventNickInUse
ObbyEventPresenceChanged
ObbyEventRawLine
ObbyEventReconnectAbandoned
ObbyEventReconnectAfter
ObbyEventRegistered
ObbyEventSaslFailed
ObbyEventServerReply
ObbyEventTypingChanged
ObbyEventVoice
Person
Someone we know about, held once however many channels we share.
RawMessage
A parsed protocol line. The types are owned rather than borrowed from the input. A borrowed Message<'a> would parse faster, but every consumer of this crate reaches it across a language boundary that cannot carry a Rust lifetime, so the copy has to happen somewhere and here is the only place it happens once.
SaslCredentials
What to authenticate with.
SaslCredentialsExternal
SaslCredentialsInput
SASL credentials for authenticating during registration, built by a host to hand to ObbyClient.new or ObbyClient.fromConfig.
SaslCredentialsPlain
SaslCredentialsScram
TurnCredentials
TURN/STUN credentials the SFU hands us on joined. These are short-lived, and nothing in the joined handshake or anywhere else in the signalling plane ever refreshes them mid-call. A call that outlives them loses its relay path with no warning; whoever integrates this signalling plane needs to leave and rejoin (or otherwise trigger a fresh joined) before that happens, since nothing here does it automatically.
VoiceParticipant
One participant's state within a `Room`. Every toggle is `OnOff` rather than bool: this is the same distinction clippy's own struct_excessive_bools lint asks for (six independent flags read equally well as a state machine's cases), and reusing OnOff rather than inventing six near-identical two-variant enums keeps it to one type.
VoiceRoom
The state of one voice room: who is in it, their kind of channel, and every participant's mic, video, speaking, deaf, screen and hand state and role.
VoiceSignal
One +obsidianirc/rtc signalling frame. Every variant is one JSON object's type. The published github.com/obbyworld/extensions/blob/main/voice.md documents only 9 of these, the wire carries 19, and this enum follows the wire. Outbound intent and inbound notification are modelled as distinct shapes where the wire actually distinguishes them (mic/video/screen/hand/speaking/silent/deaf versus the presence they get rebroadcast as; promote/demote versus role), rather than collapsed into one type as the published table's prose implies.
VoiceSignalAnswer
VoiceSignalDeaf
VoiceSignalDemote
VoiceSignalError
VoiceSignalHand
VoiceSignalIce
VoiceSignalJoin
VoiceSignalJoined
VoiceSignalLeave
VoiceSignalMic
VoiceSignalOffer
VoiceSignalPresence
VoiceSignalPromote
VoiceSignalReact
VoiceSignalRole
VoiceSignalScreen
VoiceSignalSilent
VoiceSignalSpeaking
VoiceSignalVideo
VoiceTrackHint
A hint from the SFU mapping one negotiated media line to the member it belongs to. The SFU sends mid-to-member hints so an inbound track can be attributed to the right member when the SDP's own msid is missing or unreliable. This is the minimal shape that serves that purpose; a real server may send more fields, which this simply ignores on decode.
WatchList
Who we are watching, and whether each is online.
Whois
What a WHOIS said about someone. A reply is nine numerics that arrive one at a time, so they are collected here and reported once, when the closing 318 lands. A host that reacted to each numeric would redraw a profile card nine times and show eight incomplete ones.

Enums

ConnectionPhase
How far the connection has got.
OnOff
The two states an intent frame like mic or hand toggles between.
SaslFailure
Why authentication ended without succeeding.
Severity
How serious a standard-replies message is.
TypingState
Whether we are still composing a message.
VoicePresence
The state a presence notification carries. One wire type: "presence" actually carries three incompatible shapes: a membership change (Joined/Left), a toggle (On/Off, read together with `Signal::Presence`'s kind), or an activity flag (Speaking/Silent/DeafOn/DeafOff, which carries no kind at all).
VoiceRole
Whether a room participant may publish audio and video, or only receive it.
VoiceRoomKind
Who may publish in a voice room, decided by the channel's sigil.
VoiceToggle
Which per-participant toggle a presence notification reports, for its toggle sub-shape.

Typedefs

CaseFolded = String
A nick or channel name folded under a server's casemapping. Every map keyed by a nick or a channel is keyed by this type, so that a raw String can never be used as an identity by accident. The mapping that produced it is not stored. Two CaseFolded values are only comparable when they came from the same connection, which is the only place they are ever used together.
MessageTags = List<MessageTag>
The tag section of a message, in the order it arrived. Order is kept rather than folded into a map because a round trip has to reproduce the line, and because a server may legally send the same key twice.