[][src]Struct ellidri::State

pub struct State(_);

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");

Methods

impl State[src]

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

Intialize the IRC state from the given configuration.

pub async fn peer_joined<'_>(
    &'_ self,
    addr: SocketAddr,
    queue: UnboundedSender<MessageQueueItem>
)
[src]

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.

pub async fn peer_quit<'_, '_>(
    &'_ self,
    addr: &'_ SocketAddr,
    err: Option<Error>
)
[src]

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.

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

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

Trait Implementations

impl Clone for State[src]

Auto Trait Implementations

impl !RefUnwindSafe for State

impl Send for State

impl Sync for State

impl Unpin for State

impl !UnwindSafe for State

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

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