pub struct Client { /* private fields */ }Expand description
One connection.
Implementations§
Source§impl Client
impl Client
Sourcepub fn new(config: Config) -> Self
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());Sourcepub fn handle_connected(&mut self)
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"));Sourcepub fn handle_disconnected(&mut self)
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.
Sourcepub fn tick(&mut self, now: Now)
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()));Sourcepub fn poll_timeout(&self) -> Option<u64>
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.
Sourcepub fn join(&mut self, channel: impl Into<String>, key: Option<String>)
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()));Sourcepub fn part(&mut self, channel: impl Into<String>, reason: Option<String>)
pub fn part(&mut self, channel: impl Into<String>, reason: Option<String>)
Leave a channel, with a reason the others in it see.
Sourcepub fn send_message(
&mut self,
target: impl Into<String>,
text: impl Into<String>,
)
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()),
);Sourcepub fn send_notice(
&mut self,
target: impl Into<String>,
text: impl Into<String>,
)
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.
Sourcepub fn send_action(
&mut self,
target: impl Into<String>,
text: impl Into<String>,
)
pub fn send_action( &mut self, target: impl Into<String>, text: impl Into<String>, )
Send a CTCP ACTION, the third-person form.
Sourcepub fn set_topic(&mut self, channel: impl Into<String>, topic: Option<String>)
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.
Sourcepub fn set_away(&mut self, message: Option<String>)
pub fn set_away(&mut self, message: Option<String>)
Go away with a message, or come back with None.
Sourcepub fn set_typing(&mut self, target: impl Into<String>, state: Typing)
pub fn set_typing(&mut self, target: impl Into<String>, state: Typing)
Tell a target we are composing, paused, or done.
Sourcepub fn add_reaction(
&mut self,
target: impl Into<String>,
msgid: impl Into<String>,
emoji: impl Into<String>,
)
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.
Sourcepub fn remove_reaction(
&mut self,
target: impl Into<String>,
msgid: impl Into<String>,
emoji: impl Into<String>,
)
pub fn remove_reaction( &mut self, target: impl Into<String>, msgid: impl Into<String>, emoji: impl Into<String>, )
Take one of our reactions back.
Sourcepub fn redact_message(
&mut self,
target: impl Into<String>,
msgid: impl Into<String>,
reason: Option<String>,
)
pub fn redact_message( &mut self, target: impl Into<String>, msgid: impl Into<String>, reason: Option<String>, )
Ask the server to redact a message.
Sourcepub fn mark_read(&mut self, target: impl Into<String>, at_ms: u64)
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.
Sourcepub fn fetch_history(
&mut self,
target: impl Into<String>,
before_msgid: Option<String>,
limit: u16,
)
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.
Sourcepub fn set_metadata(&mut self, key: impl Into<String>, value: Option<String>)
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.
Sourcepub fn subscribe_metadata(&mut self, keys: Vec<String>)
pub fn subscribe_metadata(&mut self, keys: Vec<String>)
Subscribe to the metadata keys we want told about.
Sourcepub fn whois(&mut self, nick: impl Into<String>)
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.
Sourcepub fn rename_channel(
&mut self,
channel: impl Into<String>,
new_name: impl Into<String>,
reason: Option<String>,
)
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.
Sourcepub fn create_invite_link(
&mut self,
channel: Option<String>,
description: Option<String>,
)
pub fn create_invite_link( &mut self, channel: Option<String>, description: Option<String>, )
Make an invitation link to a channel, or to the network when no channel is named.
Sourcepub fn list_invite_links(&mut self)
pub fn list_invite_links(&mut self)
Ask for the invitation links we have made.
Sourcepub fn delete_invite_link(&mut self, share_id: impl Into<String>)
pub fn delete_invite_link(&mut self, share_id: impl Into<String>)
Withdraw an invitation link.
Sourcepub fn redeem_invite_code(&mut self, code: impl Into<String>)
pub fn redeem_invite_code(&mut self, code: impl Into<String>)
Redeem an invitation code. Only before registering, which is the point of it.
Sourcepub fn generate_token(&mut self, service: impl Into<String>)
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.
Sourcepub fn watch_nicks(&mut self, nicks: Vec<String>)
pub fn watch_nicks(&mut self, nicks: Vec<String>)
Watch nicks, so we hear when they come online.
Sourcepub fn unwatch_nicks(&mut self, nicks: Vec<String>)
pub fn unwatch_nicks(&mut self, nicks: Vec<String>)
Stop watching nicks.
Sourcepub fn send_voice_signal(&mut self, channel: impl Into<String>, signal: Signal)
pub fn send_voice_signal(&mut self, channel: impl Into<String>, signal: Signal)
Send one voice signalling frame to a room.
Sourcepub fn send_raw_line(&mut self, line: impl Into<String>)
pub fn send_raw_line(&mut self, line: impl Into<String>)
Send one raw protocol line, for anything this API does not name.
Sourcepub fn command(&mut self, command: Command)
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.
Sourcepub fn send_line_labeled(&mut self, message: &Message) -> Option<String>
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.
Sourcepub fn handle_bytes(&mut self, data: &[u8])
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()));Sourcepub fn dropped_lines(&self) -> u64
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.
Sourcepub fn poll_transmit(&mut self) -> Option<Vec<u8>>
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"));Sourcepub fn poll_event(&mut self) -> Option<Event>
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"));Sourcepub fn send_line(&mut self, message: &Message)
pub fn send_line(&mut self, message: &Message)
Queue a message to be written. Use this for anything the engine does not model yet.
Sourcepub fn capabilities(&self) -> &Capabilities
pub fn capabilities(&self) -> &Capabilities
The capabilities the server offers and the ones we hold.
Sourcepub fn isupport(&self) -> &Isupport
pub fn isupport(&self) -> &Isupport
Everything the server advertised about itself: casemapping, prefixes, mode classes, limits.
Sourcepub fn allowed_commands(&self) -> &Commands
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.
Sourcepub fn voice_room(&self, channel: &CaseFolded) -> Option<&Room>
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.
Sourcepub fn watch_list(&self) -> &WatchList
pub fn watch_list(&self) -> &WatchList
Who we are watching for coming online, and who is here.
Sourcepub fn model(&self) -> &Model
pub fn model(&self) -> &Model
Everything the connection knows: channels, members, conversations, messages.
Sourcepub fn casemapping(&self) -> Casemapping
pub fn casemapping(&self) -> Casemapping
The casemapping to fold nicks and channel names with, from ISUPPORT.