#![allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WsOpcode {
Text,
Binary,
Ping,
Pong,
Close,
}
#[derive(Debug, Clone)]
pub struct WsFrame {
pub opcode: WsOpcode,
pub payload: Vec<u8>,
pub is_final: bool,
pub masked: bool,
}
#[derive(Debug, Default)]
pub struct WsMessageExport {
pub frames: Vec<WsFrame>,
pub url: String,
}
pub fn new_ws_export(url: &str) -> WsMessageExport {
WsMessageExport {
frames: Vec::new(),
url: url.to_owned(),
}
}
pub fn ws_send_text(export: &mut WsMessageExport, text: &str) {
export.frames.push(WsFrame {
opcode: WsOpcode::Text,
payload: text.as_bytes().to_vec(),
is_final: true,
masked: true,
});
}
pub fn ws_send_binary(export: &mut WsMessageExport, data: Vec<u8>) {
export.frames.push(WsFrame {
opcode: WsOpcode::Binary,
payload: data,
is_final: true,
masked: true,
});
}
pub fn ws_send_ping(export: &mut WsMessageExport, data: Vec<u8>) {
export.frames.push(WsFrame {
opcode: WsOpcode::Ping,
payload: data,
is_final: true,
masked: true,
});
}
pub fn ws_frame_count(export: &WsMessageExport) -> usize {
export.frames.len()
}
pub fn total_ws_bytes(export: &WsMessageExport) -> usize {
export.frames.iter().map(|f| f.payload.len()).sum()
}
pub fn frames_of_opcode(export: &WsMessageExport, opcode: WsOpcode) -> usize {
export.frames.iter().filter(|f| f.opcode == opcode).count()
}
pub fn opcode_name(op: WsOpcode) -> &'static str {
match op {
WsOpcode::Text => "text",
WsOpcode::Binary => "binary",
WsOpcode::Ping => "ping",
WsOpcode::Pong => "pong",
WsOpcode::Close => "close",
}
}
pub fn ws_export_to_json(export: &WsMessageExport) -> String {
format!(
r#"{{"url":"{}", "frame_count":{}, "total_bytes":{}}}"#,
export.url,
ws_frame_count(export),
total_ws_bytes(export)
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_export_empty() {
let e = new_ws_export("wss://localhost:8080");
assert_eq!(ws_frame_count(&e), 0);
}
#[test]
fn send_text_increments_count() {
let mut e = new_ws_export("wss://localhost:8080");
ws_send_text(&mut e, "hello");
assert_eq!(ws_frame_count(&e), 1);
}
#[test]
fn send_binary_increments_count() {
let mut e = new_ws_export("wss://localhost:8080");
ws_send_binary(&mut e, vec![1, 2, 3]);
assert_eq!(ws_frame_count(&e), 1);
}
#[test]
fn total_bytes_counted() {
let mut e = new_ws_export("wss://localhost:8080");
ws_send_text(&mut e, "hello");
assert_eq!(total_ws_bytes(&e), 5);
}
#[test]
fn frames_of_opcode_text() {
let mut e = new_ws_export("wss://localhost");
ws_send_text(&mut e, "x");
ws_send_binary(&mut e, vec![]);
assert_eq!(frames_of_opcode(&e, WsOpcode::Text), 1);
}
#[test]
fn ping_frame_opcode_correct() {
let mut e = new_ws_export("wss://localhost");
ws_send_ping(&mut e, vec![]);
assert_eq!(e.frames[0].opcode, WsOpcode::Ping);
}
#[test]
fn opcode_name_text() {
assert_eq!(opcode_name(WsOpcode::Text), "text");
}
#[test]
fn opcode_name_binary() {
assert_eq!(opcode_name(WsOpcode::Binary), "binary");
}
#[test]
fn json_contains_url() {
let e = new_ws_export("wss://ws.example.com");
assert!(ws_export_to_json(&e).contains("ws.example.com"));
}
}