Skip to main content

State

Struct State 

Source
pub struct State(/* private fields */);
Expand description

State of an IRC network.

This is used by ellidri to maintain a consistent state of the network. Note that this is just an Arc to the real data, so it’s cheap to clone and clones share the same data.

At the time of writing, this only support the client-to-server API, so the network can only consist of one server. Maybe in the long term it will support incoming messages from other servers.

The API is designed with async support only, because this type heavily relies on tokio.

§Example

// Initialize a `StateConfig` and create the state.
let sasl_backend = auth::choose_provider(config::SaslBackend::None, None).unwrap();
let state = State::new(config::State {
    domain: "ellidri.dev".to_owned(),
    ..config::State::sample()
}, sasl_backend);

// Each client is identified by its address.
let client_addr = std::net::SocketAddr::from(([127, 0, 0, 1], 12345));

// The state uses a MPSC queue and pushes the messages meant to be sent
// to the client onto the queue.
let (msg_queue, mut outgoing_msgs) = tokio::sync::mpsc::unbounded_channel();
state.peer_joined(client_addr, msg_queue).await;

// `handle_message` is used to pass messages from the client to the state.
let nick = Message::parse("NICK ser\r\n").unwrap();
let user = Message::parse("USER ser 0 * :ser\r\n").unwrap();
state.handle_message(&client_addr, nick).await;
state.handle_message(&client_addr, user).await;

// The user has registered, so the state should have pushed
// the welcome message, the motd, etc. onto the queue.
// It is safe to unwrap here while the peer is saved in the state.
let msg = outgoing_msgs.recv().await.unwrap();

// Outgoing messages implement `AsRef<[u8]>`, so they can be used with `std::io::Write`.
// They also implement `AsRef<str>` because they are UTF-8 encoded.
// Note that one call to `recv` can contain multiple IRC messages.
let msg: &str = msg.as_ref();
let mut lines = msg.split("\r\n");

// The first IRC message from the server is RPL_WELCOME.
assert_eq!(lines.next().unwrap(),
           ":ellidri.dev 001 ser :Welcome home, ser!ser@127.0.0.1");

Implementations§

Source§

impl State

Source

pub fn new(config: State, auth_provider: Box<dyn Provider>) -> Self

Intialize the IRC state from the given configuration.

Source

pub async fn peer_joined( &self, addr: SocketAddr, queue: UnboundedSender<MessageQueueItem>, )

Adds a new connection to the state.

Each connection is identified by its address. The queue is used to push messages back to the peer.

Source

pub async fn peer_quit(&self, addr: &SocketAddr, err: Option<Error>)

Removes the given connection from the state, with an optional error.

If the peer has quit unexpctedly, err should be set to Some and reflect the cause of the quit, so that other peers can be correctly informed.

Source

pub async fn handle_message( &self, addr: &SocketAddr, msg: Message<'_>, ) -> Result<(), ()>

Updates the state according to the given message from the given client.

Trait Implementations§

Source§

impl Clone for State

Source§

fn clone(&self) -> State

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl Freeze for State

§

impl !RefUnwindSafe for State

§

impl Send for State

§

impl Sync for State

§

impl Unpin for State

§

impl UnsafeUnpin for State

§

impl !UnwindSafe for State

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V