Skip to content

Commit 749b75a

Browse files
committed
Client work
1 parent 2ed8916 commit 749b75a

File tree

4 files changed

+64
-44
lines changed

4 files changed

+64
-44
lines changed

src/irc/client.rs

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,53 +5,47 @@ pub mod capabilities;
55
mod test;
66

77
use buffer::Buffer;
8-
use web_sys::WebSocket;
9-
use yew::AttrValue;
8+
use capabilities::{CapNegotiator, Capability};
109

1110
use super::parser::Message;
1211

13-
pub trait Socket {
14-
type Error;
15-
16-
fn new(host: &str) -> Result<Self, Self::Error>
17-
where
18-
Self: Sized;
12+
#[derive(Debug, PartialEq, Clone)]
13+
enum ClientState {
14+
PreCapLs,
15+
CapLs,
16+
//CapReq,
1917
}
2018

21-
impl Socket for WebSocket {
22-
type Error = ();
23-
fn new(host: &str) -> Result<Self, Error> {
24-
match WebSocket::new(host) {
25-
Ok(ws) => Ok(ws),
26-
Err(_) => Err(()),
27-
}
28-
}
29-
}
19+
#[derive(Debug, Clone, PartialEq)]
20+
pub struct Error {}
3021

3122
#[derive(Debug, Clone, PartialEq)]
3223
pub struct Client {
33-
pub capabilities: Vec<Capability>,
24+
state: ClientState,
25+
cap_negotiator: CapNegotiator,
3426
pub buffers: Vec<Buffer>,
3527
}
3628

37-
// TODO: proper error type
38-
type Error = ();
39-
40-
///
41-
type Messages = Vec<Message>;
42-
4329
impl Client {
30+
// Supported list of capabilities
31+
pub fn supported_capabilities() -> Vec<Capability> {
32+
vec![Capability::new("sasl")]
33+
}
34+
4435
pub fn new() -> Self {
4536
Client {
46-
capabilities: vec![],
37+
state: ClientState::PreCapLs,
38+
cap_negotiator: CapNegotiator::request(Self::supported_capabilities()),
4739
buffers: vec![],
4840
}
4941
}
5042

51-
pub fn request_capabilities(_capabilities: Vec<Capability>) -> Result<Messages, Error> {
52-
Ok(vec![Message::cmd("CAP").param("LS").build()])
43+
pub fn request_capabilities(&mut self) -> Message {
44+
self.state = ClientState::CapLs;
45+
self.cap_negotiator.ls(Some("302"))
5346
}
54-
}
5547

56-
#[derive(Debug, Clone, PartialEq)]
57-
pub struct Capability(pub AttrValue);
48+
pub fn handle(&mut self, _message: &Message) -> Result<(), Error> {
49+
Ok(())
50+
}
51+
}

src/irc/client/capabilities.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,29 @@ use yew::AttrValue;
55
/// https://ircv3.net/specs/extensions/capability-negotiation.html
66
use crate::irc::parser::{Command, Message, MessageBuilderError};
77

8-
use super::Capability;
9-
108
#[cfg(test)]
119
mod test;
1210

1311
type Result = std::result::Result<Messages, Error>;
1412
type Messages = Vec<Message>;
1513

14+
#[derive(Debug, Clone, PartialEq)]
15+
pub struct Capability(pub AttrValue);
16+
17+
impl Capability {
18+
pub fn new(value: &str) -> Self {
19+
Capability(value.to_owned().into())
20+
}
21+
}
22+
1623
#[derive(Debug)]
1724
pub enum Error {
1825
UnexpectedCommand(Command),
1926
UnexpectedSubcommand(String),
2027
MessageBuilderError(MessageBuilderError),
2128
}
2229

30+
#[derive(Debug, Clone, PartialEq)]
2331
pub struct CapNegotiator {
2432
pub requested: Vec<Capability>,
2533
pub acknowledged: Vec<Capability>,
@@ -35,7 +43,7 @@ impl CapNegotiator {
3543
}
3644
}
3745

38-
pub fn ls(&self, version: Option<String>) -> Message {
46+
pub fn ls(&self, version: Option<&str>) -> Message {
3947
let mut builder = Message::cmd("CAP").param("LS");
4048

4149
if let Some(version) = version {

src/irc/client/test.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,30 @@
1-
use websocket::ClientBuilder;
1+
use websocket::{stream::sync::NetworkStream, sync::Client, ClientBuilder, OwnedMessage};
22

3-
#[test]
4-
#[ignore = "requires dotenv to be set up."]
5-
fn test_client_websocket() {
3+
use super::{capabilities::CapNegotiator, Capability};
4+
5+
fn connect() -> Client<Box<dyn NetworkStream + Send>> {
66
let host = dotenv::var("WEBSOCKET_HOST").expect("");
77
println!("Connectin websocket to {host}");
8-
let client = ClientBuilder::new(&host).unwrap().connect(None);
9-
if let Err(err) = client {
10-
println!("Failed to connect websocket to {host}:\n{err}");
11-
assert!(false);
8+
match ClientBuilder::new(&host).unwrap().connect(None) {
9+
Err(err) => {
10+
panic!("Failed to connect websocket to {host}:\n{err}")
11+
}
12+
Ok(client) => client,
13+
}
14+
}
15+
16+
#[test]
17+
#[ignore = "requires dotenv to be set up."]
18+
fn integrate_client_with_websocket() {
19+
let mut client = connect();
20+
let capabilities = CapNegotiator::request(vec![Capability("sasl".into())]);
21+
22+
let msg = capabilities.ls(Some("302".into()));
23+
client
24+
.send_message(&OwnedMessage::Text(msg.to_string()))
25+
.unwrap();
26+
27+
if let Ok(msg) = client.recv_message() {
28+
println!("{msg:?}");
1229
}
1330
}

src/ui/app/home.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ fn example_buffer() -> Buffer {
5050
pub fn HomePage(props: &HomeProps) -> Html {
5151
let nav = use_navigator().unwrap();
5252

53-
let client = use_state_eq(|| Client {
54-
capabilities: vec![],
55-
buffers: vec![example_buffer()],
53+
let client = use_state_eq(|| {
54+
let mut c = Client::new();
55+
c.buffers.push(example_buffer());
56+
c
5657
});
5758

5859
if props.settings.is_none() {

0 commit comments

Comments
 (0)