Skip to main content

Client

Struct Client 

Source
pub struct Client { /* private fields */ }
Expand description

One connection.

Implementations§

Source§

impl Client

Source

pub fn new(config: Config) -> Self

Build an engine that has not connected yet. Nothing is written until Client::handle_connected.

use obby_client::{Client, Config, Phase};

let mut client = Client::new(Config::new("mynick"));
assert_eq!(client.nick(), "mynick");
assert_eq!(client.phase(), Phase::Disconnected);
assert!(client.poll_transmit().is_none());
Source

pub fn handle_connected(&mut self)

Tell the engine the transport is up. This queues the registration burst.

The host calls this once the socket is open and the TLS handshake, if any, has finished. The engine has no way to know that on its own.

let mut client = Client::new(Config::new("mynick"));
client.handle_connected();

let mut sent = Vec::new();
while let Some(bytes) = client.poll_transmit() {
    sent.extend_from_slice(&bytes);
}
assert!(sent.starts_with(b"CAP LS 302\r\n"));
assert!(sent.ends_with(b"USER mynick 0 * mynick\r\n"));
Source

pub fn handle_disconnected(&mut self)

Tell the engine its transport died. The model survives, so a reconnect can resume from it.

The engine decides when to try again and says so with Event::ReconnectAfter. The host owns every socket, and this is the only thing it has to report.

Source

pub fn tick(&mut self, now: Now)

Advance the clock. Whatever has fallen due happens here.

The host supplies both clocks because the engine has neither: the monotonic one drives every deadline, and the wall clock only stamps a message the server did not stamp itself.

let mut client = Client::new(Config::new("mynick"));
client.handle_connected();
while client.poll_transmit().is_some() {}

// sleeping until exactly the next deadline is all a host's loop has to do
let due_ms = client.poll_timeout().expect("the keepalive is armed on connect");
client.tick(Now {
    monotonic_ms: due_ms,
    unix_ms: 1_788_688_800_000,
});
assert_eq!(client.poll_transmit(), Some(b"PING mynick\r\n".to_vec()));
Source

pub fn poll_timeout(&self) -> Option<u64>

When Client::tick next has something to do, as a monotonic instant.

A host can sleep until exactly then rather than waking on a fixed interval.

Source

pub fn join(&mut self, channel: impl Into<String>, key: Option<String>)

Join a channel, with its key when it has one.

let mut client = Client::new(Config::new("mynick"));
client.join("#obby", None);
client.join("#staff", Some("hunter2".to_string()));

assert_eq!(client.poll_transmit(), Some(b"JOIN #obby\r\n".to_vec()));
assert_eq!(client.poll_transmit(), Some(b"JOIN #staff hunter2\r\n".to_vec()));
Source

pub fn part(&mut self, channel: impl Into<String>, reason: Option<String>)

Leave a channel, with a reason the others in it see.

Source

pub fn send_message( &mut self, target: impl Into<String>, text: impl Into<String>, )

Say something to a channel or a person.

let mut client = Client::new(Config::new("mynick"));
client.send_message("#obby", "hello there");

assert_eq!(
    client.poll_transmit(),
    Some(b"PRIVMSG #obby :hello there\r\n".to_vec()),
);
Source

pub fn send_notice( &mut self, target: impl Into<String>, text: impl Into<String>, )

Send a notice, which by convention must never be auto-replied to.

Source

pub fn send_action( &mut self, target: impl Into<String>, text: impl Into<String>, )

Send a CTCP ACTION, the third-person form.

Source

pub fn set_nick(&mut self, nick: impl Into<String>)

Change our nick.

Source

pub fn set_topic(&mut self, channel: impl Into<String>, topic: Option<String>)

Set a channel’s topic, or ask for the current one with None.

Source

pub fn set_away(&mut self, message: Option<String>)

Go away with a message, or come back with None.

Source

pub fn set_typing(&mut self, target: impl Into<String>, state: Typing)

Tell a target we are composing, paused, or done.

Source

pub fn add_reaction( &mut self, target: impl Into<String>, msgid: impl Into<String>, emoji: impl Into<String>, )

React to a message with an emoji.

Source

pub fn remove_reaction( &mut self, target: impl Into<String>, msgid: impl Into<String>, emoji: impl Into<String>, )

Take one of our reactions back.

Source

pub fn redact_message( &mut self, target: impl Into<String>, msgid: impl Into<String>, reason: Option<String>, )

Ask the server to redact a message.

Source

pub fn mark_read(&mut self, target: impl Into<String>, at_ms: u64)

Move our read marker in a target, at a time in milliseconds since the Unix epoch.

Source

pub fn fetch_history( &mut self, target: impl Into<String>, before_msgid: Option<String>, limit: u16, )

Ask for older messages in a target, before the message with this id.

Source

pub fn set_metadata(&mut self, key: impl Into<String>, value: Option<String>)

Set one of our own metadata keys, or clear it with None.

Source

pub fn subscribe_metadata(&mut self, keys: Vec<String>)

Subscribe to the metadata keys we want told about.

Source

pub fn whois(&mut self, nick: impl Into<String>)

Ask the server everything it will say about someone.

The record lands in the model under the folded nick and arrives as one Change::WhoisReceived when the reply finishes.

Source

pub fn rename_channel( &mut self, channel: impl Into<String>, new_name: impl Into<String>, reason: Option<String>, )

Rename a channel, keeping everyone in it and everything said in it.

Make an invitation link to a channel, or to the network when no channel is named.

Ask for the invitation links we have made.

Withdraw an invitation link.

Source

pub fn redeem_invite_code(&mut self, code: impl Into<String>)

Redeem an invitation code. Only before registering, which is the point of it.

Source

pub fn generate_token(&mut self, service: impl Into<String>)

Mint a bearer token for one of the network’s services, such as its file host.

The token comes back as an Event::AuthToken.

Source

pub fn watch_nicks(&mut self, nicks: Vec<String>)

Watch nicks, so we hear when they come online.

Source

pub fn unwatch_nicks(&mut self, nicks: Vec<String>)

Stop watching nicks.

Source

pub fn send_voice_signal(&mut self, channel: impl Into<String>, signal: Signal)

Send one voice signalling frame to a room.

Source

pub fn quit(&mut self, reason: Option<String>)

Leave the server, with a reason the others see.

Source

pub fn send_raw_line(&mut self, line: impl Into<String>)

Send one raw protocol line, for anything this API does not name.

Source

pub fn command(&mut self, command: Command)

Do something on this connection.

Anything the server will echo back to us is left for that echo to record, so a message never lands twice. Without echo-message there is no echo coming, so we record it ourselves from the same line we sent, through the same path that would have handled the echo.

Source

pub fn send_line_labeled(&mut self, message: &Message) -> Option<String>

Send a command and correlate whatever the server sends back with it.

Returns the label when labeled-response is in force. Without that capability the command still goes out, unlabelled, because a server that does not support it would only be confused by the tag.

Source

pub fn handle_bytes(&mut self, data: &[u8])

Feed whatever the transport read. Partial lines are held until the rest arrives.

let mut client = Client::new(Config::new("mynick"));

// a socket read splits wherever it likes, and the engine holds the remainder
client.handle_bytes(b"PING :ab");
assert!(client.poll_transmit().is_none());

client.handle_bytes(b"c\r\n");
assert_eq!(client.poll_transmit(), Some(b"PONG abc\r\n".to_vec()));
Source

pub fn dropped_lines(&self) -> u64

How many inbound lines were dropped, either unparseable or longer than we will hold.

Nothing is returned to the host when a line is dropped, because there is nothing it could do about it. The count is here so a host can see that it is happening at all.

Source

pub fn poll_transmit(&mut self) -> Option<Vec<u8>>

Bytes the host should write to the transport, or None when there are none.

let mut client = Client::new(Config::new("mynick"));
client.handle_connected();

let mut socket = Vec::new();
while let Some(bytes) = client.poll_transmit() {
    socket.extend_from_slice(&bytes); // a real host writes these to its socket
}
assert!(socket.starts_with(b"CAP LS 302\r\n"));
Source

pub fn poll_event(&mut self) -> Option<Event>

The next thing that happened, or None when the host is caught up.

let mut client = Client::new(Config::new("mynick"));
client.handle_bytes(b":irc.example.org 001 mynick :Welcome\r\n");

let mut registered_as = None;
while let Some(event) = client.poll_event() {
    if let Event::Registered { nick } = event {
        registered_as = Some(nick);
    }
}
assert_eq!(registered_as.as_deref(), Some("mynick"));
Source

pub fn send_line(&mut self, message: &Message)

Queue a message to be written. Use this for anything the engine does not model yet.

Source

pub fn phase(&self) -> Phase

How far registration has got.

Source

pub fn nick(&self) -> &str

The nick the server currently knows us by.

Source

pub fn capabilities(&self) -> &Capabilities

The capabilities the server offers and the ones we hold.

Source

pub fn isupport(&self) -> &Isupport

Everything the server advertised about itself: casemapping, prefixes, mode classes, limits.

Source

pub fn allowed_commands(&self) -> &Commands

The commands the server says we may currently use.

Empty until the server sends its list, which it does on connect and again whenever what we may do changes, such as after an OPER.

Source

pub fn bots(&self) -> &Bots

The bots the server has told us about, keyed by their folded nick.

Source

pub fn voice_room(&self, channel: &CaseFolded) -> Option<&Room>

The voice room for a channel, once we have heard any signalling for it.

Signalling and room state only. Every track, codec and peer connection is the host’s, and nothing here knows they exist.

Source

pub fn watch_list(&self) -> &WatchList

Who we are watching for coming online, and who is here.

Source

pub fn model(&self) -> &Model

Everything the connection knows: channels, members, conversations, messages.

Source

pub fn casemapping(&self) -> Casemapping

The casemapping to fold nicks and channel names with, from ISUPPORT.

Trait Implementations§

Source§

impl Debug for Client

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.